C# 有哪些显著的缺点?

240 天前
 w568w

之前久仰 C# 大名,但一直没实际接触过,一是感觉微软的东西都不靠谱,二是觉得这语言只有游戏产业和 ASP.NET 服务器在用,三是不知道从哪里留下了「 C# 运行性能特别差」的印象。

今天在 Windows 上写了个小数据处理脚本,出于好奇去安装了一下 .NET 9 ,用 GPT 把 Python 转成了 C# 去跑,发现这东西跑起来飞快,比 Python 快了不止七八倍,CPU 也吃满了。

继而去查了一下 Debian 的 The Computer Language Benchmarks Game 。不看不知道,好家伙,现在 C# aot 都能在 CLBG 排到 Go 头上去了:

Language elapsed secs / fastest
Intel C 1.1
C 1.3
C# aot 1.5
Java 1.5
Go 1.6

虽然性能测试和 Java 差不多,但内存占用要少 50%~70%。试了一下 AOT 编译,编译出来就一个 4~5MB 可执行文件,体积很小也无依赖,额外开销基本和 Rust 、C++ 那些原生语言差不多无感。

但这可是带 GC 的「重型」语言啊,微软这几年的优化确实厉害。

所以感觉这语言挺有意思,准备最近多花时间当兴趣学习一下,但还是对微软的东西不是很放心。问问各位 C# 开发:C# 有什么特别明显缺点或者写起来卡手的地方吗? 提前谢谢大家。

5456 次点击
所在节点    C#
45 条回复
HFX3389
240 天前
> 试了一下 AOT 编译,编译出来就一个 4~5MB 可执行文件,体积很小也无依赖

那这个编译出来的可执行文件能够在没有安装运行环境.NET 9 下运行吗
gadfly3173
240 天前
linux 上的缺点:C#的 FileSystemWatcher 只支持每个实例侦听一个目录,并且每侦听一个目录就需要创建一个 inotify 实例,而一般 linux 的 inotify 实例上限一般是 128 。如果你要用 C#做一个需要监听多个目录变化的程序,那么很容易达到这个上限,导致系统上无法再创建任何 inotify 实例。这个问题看起来 node.js 和 java 都是没有的。😓

dotnet/runtime#62869
chenqh
240 天前
@z1829909 python 没有 JIT 啊,一个核都算了,反正 web 小项目可以把进程当线程用.
gadfly3173
240 天前
@HFX3389 可以的,publish 的时候指定--self-contained 就行。一个使用.net9 aot 编译的例子就是 sourcegit-scm/sourcegit
csys
240 天前
最致命的问题是生态,尤其是在国内

其它的问题比如函数染色是许多其它编程语言也有的,但是生态完全是独一份的致命伤,而且越来越致命

另一个隐藏的问题是微软,微软给 C#/.NET 提供了持续的高质量的支持,但是又不断地扼杀 C#/.NET 社区
Akiya
240 天前
缺点就是你用了 C#之后再用别的语言就用的没那么舒服了
Bronya
240 天前
我自己写程序经常用 C#,手上还有个用 blazor 写的面板工具,一些脚本处理也都是用 dotnet-script 方便一键运行,需要图形界面的话就用 WPF 搞。
目前为止遇到的问题有(包括语言及生态):

* AOT 不支持交叉编译
* self contained 模式下部分库对修剪功能支持不到位,导致想写个程序给没有安装 run time 的机器上运行时,必须打包整个运行时,会使打包文件过大(几行代码打包下载近百兆,修剪了又会报错。)。
* rider 对 blazor 热重载支持不如 vs ,经常需要重启。而 vs 又经常无法识别代码,经常没有问题的代码会报错,关闭重新打开就又好了( vs 2022 )。
* 经常会纠结到底用不用可空类型。
* 有些东西如果不按照官方的推荐搞,会变得很麻烦。比如 blazor 中的认证,如果不用官方的 Idendity 包,会很麻烦,但是官方包里东西又太多了,我仅仅想要个用户名密码验证而已。
* 异步函数传染问题(这点真没 go 方便)
* 没有好的方式写安卓应用( MAUI 问题太多了)
ZGame
240 天前
相比较 java 来说,优点是写起来太顺畅了。 缺点是没有布道师,和相应的广泛的开源生态和 copy 代码。
z1829909
239 天前
@chenqh 一般 python 的 web 项目不也是起多个进程,每个进程里走异步 io ,如果纯单进程 cpu 满了,会影响他调度造成超时。
w568w
239 天前
@geelaw 感谢。关于数组协变,我的想法是不是 C# 根本不应该支持在数组上自动协变?下面也有朋友提到协变后的数组写入其他类型的元素是运行时错误,极难检查。

@niubee1 @ShinichiYao 此话怎讲?

@DTCPSS 看了一下,很有收获,确实把语言中最肮脏的设计都列出来了。(好在 Java 等 GC 语言也共享了几个,比如无 Destructor 。)

@gadfly3173 看起来也没有那么难修复,感觉是微软特有的 Windows 中心思维在作祟。不知道 Mono 有没有同样的问题?

@csys @ZGame C# 的生态非常差吗?我看 NuGet 上的库挺多的(虽然基本都是围绕 Windows 转)。

@Bronya 感谢。「异步函数传染」这点,其实我写 Rust 、Python 、Dart 、Kotlin…… 早就习惯了,所有函数全部染色就好了,现在写 Go 好像也没什么感觉了。「 Self-contained 修剪不到位」这个确实是有点硬伤,我得多写程序测试测试。
geelaw
239 天前
@w568w #30 数组可变性是从 JVM 抄到 CLR 里最恶心的特性之一,根本不应该支持。解决方法是 public readonly struct S<T> where T : class { public readonly T O; public S(T o) { O = o; } } 然后用 S<T>[]。
Jlzeng
239 天前
aot 和很多现代特性不兼容(反射、emit 、动态加载 dll )没法既要又要。
chenqh
239 天前
@z1829909 但是单进程 cpu 满了,这种好查啊
yuandong
239 天前
国内大公司用的少,优秀的 C#程序员也少
hez2010
235 天前
@geelaw 其实 int 和 enum 的类型转换那块儿是对 C++ 行为的兼容,类似的还有 0 可以不需要转换就能赋值给任何的 enum 。
geelaw
234 天前
@hez2010 #35 我说的是装箱拆箱的问题,不是 int 和 enum 存在转换的问题。

StringSpiltOptions e = (StringSplitOptions)1;
int i = (int)e;

不是

object o = (StringSplitOptions)1;
int i1 = (int)o; // bad, but works
int i2 = (int)(StringSplitOptions)o; // good, and works

装箱拆箱在 C++ 标准里最接近的是 std::any_cast ,它并不允许把存放了 enum 的 any 通过 any_cast 变成 int ,但这个论证无意义,因为 C++ 的 any 比 CLR 晚了很久。

另一个接近的是 C++ 允许 std-layout type 的 pointer 和它 first member 的 pointer 做 reinterpret_cast ,但是 C# 里面装箱后的值类型(根据 CLR 定义,这是和值类型不同的、一个自动产生的类型)应该理解为多态类型(“具有虚表”),此时不是 std-layout ,所以也不适用这个类比。
sagaxu
233 天前
最大的缺点是生态差,

比如这个会导致异步 IO 被阻塞的 mysql connector 的 bug ,2013 年提出,2023 年才修复
https://bugs.mysql.com/bug.php?id=70111

比如微信支付 SDK ,2024 年了还不提供.net
https://pay.weixin.qq.com/doc/v3/merchant/4012076498
hez2010
233 天前
@sagaxu 微软支付不提供 .net 版 sdk 并不妨碍第三方提供完整的 sdk: https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat

至于 mysql connector ,感觉用 .net 的更多还是用 pgsql ,而不是 mysql
nebkad
230 天前
ref struct, struct, record struct, readonly struct.....
过于甜了,最近几年加的语法糖太多显得很乱,功能不是很正交,类型系统瑕疵很多,譬如楼上 GeeLaw 提及的
现在好像 ref struct 还不能实现 interface ( C# 13 据说可以了?)然而对于高性能 IO 来说 ref struct 又很重要
但是 LINQ 真的值得吹爆,至今找不到竞品
shiloh595
224 天前
LINQ is best:)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1102753

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX