微软推出C# 8可空引用类型的动机及Method1与Method2的核心差异探讨
嘿,作为C#新手搞不懂可空引用类型(NRTs)太正常了——我刚接触的时候也对着这个?符号挠头好久!先给你唠清楚微软为啥要在C# 8里加这个特性,再拆解那两个方法的核心差异。
微软为啥要搞可空引用类型?
之前的C#里,所有引用类型(比如string、自定义类)默认都是“可空”的——你可以给它们赋值null,编译器不会拦着你,但运行时一旦你不小心调用了null对象的成员,就会炸出NullReferenceException,这绝对是C#开发者最头疼的Bug之一,而且很多时候要到运行时才会暴露出来。
微软搞可空引用类型的核心目的就是把空值检查从“运行时”提前到“编译时”,帮你在写代码的时候就发现潜在的空值问题,而不是等程序跑起来崩了才排查。另外,它还能让你的代码意图更清晰——通过?符号,直接在签名里告诉其他开发者“这个变量/参数允许为null”,不用再靠注释或者猜来传递信息。
Method1和Method2的核心差异
这俩方法的区别全在#nullable指令和参数的可空标注上,核心差异有这几点:
1. 参数的空值语义明确性完全不同
Method1(string? arg):在#nullable enable的区域里,string?是明确的可空引用类型标注——相当于你直接告诉编译器和其他开发者:“这个参数可以接受null,是我故意这么设计的”。Method2(string arg):在#nullable disable的区域里,回到了C# 8之前的传统行为——string虽然语法上没有?,但编译器不会帮你判断它能不能为null,你传null进去编译器也不会拦着,但这时候的空值风险是隐藏的。
2. 编译器的空值检查力度不一样
- 写Method1的代码时,如果你直接用
arg的成员(比如arg.Length),编译器会立刻弹出警告:“可能为空引用”,逼着你先做if (arg != null)的判空处理,从源头避免空引用异常。 - 写Method2的代码时,哪怕你明知道传了null进去,编译器也不会给任何空值相关的警告——它默认你自己会处理空值问题,不会帮你做静态检查,坑很容易藏在这里。
3. 代码意图的传递效率不同
- Method1的签名本身就是最好的文档:其他开发者一眼看到
string?就知道这个参数可以传null,不用去翻注释或者看方法内部实现,沟通成本极低。 - Method2的签名就很模糊:别人看到
string arg,根本不确定到底能不能传null,要么去查文档,要么得读你的方法代码才能确认,很容易因为误解踩坑。
最后要提一句:可空引用类型是编译时的静态检查,不会改变运行时的行为——比如你硬给Method1传null,或者给Method2传null,运行时的效果是一样的,但编译时的提示和防护完全不同,这才是关键。
内容的提问来源于stack exchange,提问作者Aarnihauta
相关产品推荐
相关产品推荐

