大量廉价可替换的劳动力。
技术理由不是没有,而是多到罄竹难书,但都算是细节,相比起来算是次要的。
真要说就有一个有代表性的:因为 project leader 水平问题,经常半吊子,完全无法一步到位,发版就是打补丁还不是 Java 那种用户自下而上推的那种,搞得底层生态发展自上而下地得半死不活。
比如 C# 2~4 ,先搞什么 anonymous method 再加 lambda 。你要是上道点,直接加 lambda 会死?特别是要知道历史上本来就先有的 lambda ,哪来你 method 什么事(当然严格来说你抄 Java 就注定是败笔了;类似的问题还有到处 method 不给 free function 再用 extension method 之类擦屁股等等,细想起来到处都是)。
虽然多加一个特性表面上就是多给了个选择,但是这类玩意儿根本是自上而下牵一发而动全身的,只有从上游推广,(因为传统的静态语言的先天问题)用户自己除非有本事整个重新实现一遍(也就有本事整出半吊子,比如 Mono )都没法 derive (不像 JS 起码有自举的 Babel 这类; dynamic 这种补丁就算了),结果就是用户不得不被迫浪费精力了解这种半吊子设计,要么跳车要么就习惯基础技术时刻落伍。
要命的是这种微创新累积问题不是一个两个,官方还成习惯了,丝毫就没表现出要怎么克服改进。
而各种兼容性问题(像 @
vone 提的)则是这种问题的一类表面上的体现。其实这种症状要只出现个例也还不是问题,但是多了工程上就很劝退了。
你要是 Java ,这还真不是太大的问题——本来 Java 用户平均来讲就是工业界里最容易在这方面被糊弄的又有强大的钉子户传统,最不怕的就是语言层次上的一成不变,嫌没事干可以头铁手动日 CheckedException 或者人肉翻译 XML 到 stacktrace 玩儿然后强行算成 framework 类似物的 KPI ,大多数用户都会默默接受习以为常;
但.NET 除了软粉以外很多也就是从被 Java 糊弄不爽的状况下叛逃过去的,用户基数一开始就是问题,还玩碎片化?(
还有大明湖畔的.NET CF……)岂不是才离虎口又入狼窝?
而且这么多年了微软阵营的开发者应该都知道上游对坚持技术方向的软弱性和自己选择跟微软走的沉没成本。看这堆特性刷版本号的敏捷套路玩多了,越来越多的 Java 开发者即便不满,也都不愿意上车了。
要知道大多数开发者其实日常是摸不到 JVM/CLR 之类垃圾在哪的,所以深刻体会到 Java 的烂以后,这年头 Java 开发者流行跳其它 JVM 语言,转型失败风险小反复横跳难度低,
哪像你.NET 看起来那么 49 年入国军的?
别的用户转.NET 么,生态位问题,不会是主流路径。
毕竟历史上你.NET 的中坚力量 C#造出来先天就是怼 Java 的(.NET 本质是召唤 COM 加成,只要接受微软全家桶能受得了 0x800 稀里哗啦的 HRESULT ,不用白不用),所以吃不死 Java 用户,也没什么盼头了。
别的比如搞 C++的,因为嫌弃语言用起来麻烦跳 Rust 之类还算正常,
但跳.NET 的理由基本只会是被迫写 UI 然后还只需要应付 Windows ,而不是说 C#之类真比 C++用起来舒服到哪去了(光一个 using 的缩进就够欠扁了)。