我认为 C# 几个重要的设计缺陷

我认为 C# 几个重要的设计缺陷

虽然使用C#代码写了很多年的业务代码, 现在发现很多语法已经看不懂了, 不可否认有个人的原因, 但我也觉得也有C#自身设计问题的原因, 这个文章总结一些我认为C#设计的不好的地方.

目前我个人仅推荐在桌面客户端项目中使用C#, 其他场景能用Java就用Java.

优先 PascalCase 命名规范

类属性和方法也推荐使用 PascalCase 命名规范, 这一点最弱智了.

public class YourObject{
   public MyObject MyObject{get ;set ;}  // 这里两个 MyObject, 哪个是类名, 哪个是实例?
}

对比 Java, 命名规范就做的相当好.

async 的传染性

async 底层以来编译器生成的复杂状态机, 简化了代码层的异步机制, 使得代码非常简洁. 但它和传统的同步代码写法完全不兼容, 这个特性极具传染性, 一旦一个方法变成了 async, 它所有调用链上的都必须变成 async, 否则会引起死锁或性能问题, 它无法很好地和传统的同步方法混用. 微软似乎不考虑这对大型项目或长期项目的破坏力有大多.

现在社区有些新的类库甚至不提供同步版实现, 仅仅提供了async的方法实现.

对比 Java 21, 使用虚拟线程, 写出来的异步代码完全兼容原来的同步代码.
当然Java 的 CompletableFuture和其他一些异步框架(Spring WebFlux、Project Reactor 和 RxJava)也有C# async的传染性问题.

nullable 引用类型的传染性

为了减少 NullReferenceException, 试图使用编译器增强来解决这个问题, 出发点是好的, 但设计同 async 一样糟糕, 代码中会充斥这大量的 ?! 符号, 可读性变得非常差.

对比 Java, 很克制地引用了 Optional 来解决空指针异常, 将异常解决的责任权交给开发人员.

顶层语句

C# 9甚至引入了顶层语句特性, 直接破坏了面向对象的直观性, 加重了代码理解的负担, 试图抢占一下脚本语言的市场, 但我预判又是一个得不偿失的设计, 终究会沦为鸡肋.

反观 Java 官方的各种决定都显得深思熟虑. 要让面向对象的语言达成脚本脚本语言的效果, 单靠一个顶层语句肯定是不够的. Java中有个JBang项目做的非常好, 将依赖/编译/部署/运行都考虑到了.

record 类型居然还分 record class 和 record structure, 还有各种奇怪的 ref structure/ref readonly 组合

作为企业级编程语言, 这些设计就显得更随意了, 理由是要获得极致的性能, 如果是绝对的追求性能场景, 大概率一开始就不会选用C#了, 反倒将语法搞得如此复杂.

posted @ 2026-05-31 11:02  harrychinese  阅读(6)  评论(0)    收藏  举报