C# 有哪些显著的缺点?

3 天前
 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# 有什么特别明显缺点或者写起来卡手的地方吗? 提前谢谢大家。

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

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

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

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

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

* AOT 不支持交叉编译
* self contained 模式下部分库对修剪功能支持不到位,导致想写个程序给没有安装 run time 的机器上运行时,必须打包整个运行时,会使打包文件过大(几行代码打包下载近百兆,修剪了又会报错。)。
* rider 对 blazor 热重载支持不如 vs ,经常需要重启。而 vs 又经常无法识别代码,经常没有问题的代码会报错,关闭重新打开就又好了( vs 2022 )。
* 经常会纠结到底用不用可空类型。
* 有些东西如果不按照官方的推荐搞,会变得很麻烦。比如 blazor 中的认证,如果不用官方的 Idendity 包,会很麻烦,但是官方包里东西又太多了,我仅仅想要个用户名密码验证而已。
* 异步函数传染问题(这点真没 go 方便)
* 没有好的方式写安卓应用( MAUI 问题太多了)
ZGame
2 天前
相比较 java 来说,优点是写起来太顺畅了。 缺点是没有布道师,和相应的广泛的开源生态和 copy 代码。
z1829909
2 天前
@chenqh 一般 python 的 web 项目不也是起多个进程,每个进程里走异步 io ,如果纯单进程 cpu 满了,会影响他调度造成超时。
w568w
2 天前
@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
2 天前
@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
2 天前
aot 和很多现代特性不兼容(反射、emit 、动态加载 dll )没法既要又要。
chenqh
2 天前
@z1829909 但是单进程 cpu 满了,这种好查啊
yuandong
1 天前
国内大公司用的少,优秀的 C#程序员也少

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

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

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

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

© 2021 V2EX