1. 入门
为啥NRT要单独开启?
Nullable Reference Types(NRT)可不只是语法糖,它是编译器帮你抓null相关bug的好帮手。但因为历史原因,这个模式在老项目里默认是关着的——为了不破坏兼容性。如果你用的是新版.NET(比如.NET 7、8或9),NRT大概率已经自动开了。但如果你的项目比较老,或者你想手动控制,那就得自己动手开。
Nullable Reference Types模式到底干嘛的?
这个模式一开,编译器就会分析哪些引用类型变量可能是null,哪些不是。它不会影响程序运行,但会很热情地给你警告,看到有风险就提醒。这是写出靠谱、易懂又稳定代码的好办法。
怎么知道NRT开没开?
如果你是.NET 6或更高的新项目,NRT大概率已经开了。但啥情况都有,咱们来查查!
- 打开项目文件。一般就是.csproj结尾的文件。
- 在第一个<PropertyGroup>标签里找或者加上<Nullable>设置。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
启用NRT的
.csproj文件示例
如果你看到<Nullable>disable</Nullable>,那NRT就是关着的。
2. 怎么启用NRT模式
通过.csproj——全项目生效
- 打开(或新建).csproj文件。
- 在<PropertyGroup>块里加或改这一行:
<Nullable>enable</Nullable>
现在编译器会盯着你项目里所有.cs文件,遇到可能有null风险的地方就会警告你。
为啥要这样?
因为这是全局设置。从现在起,整个项目都按新规矩来:null都得小心,马虎不得!
只对某些文件或代码块生效
如果你还没准备好全项目都用严格模式,可以先在某些文件里练练手。用预处理指令就行:
#nullable enable
string? value = null; // 这里分析是开的
#nullable disable
string legacyValue = null; // 这里就关了
#nullable restore
- #nullable enable——开启检查直到文件结尾。
- #nullable disable——关闭检查。
- #nullable restore——恢复.csproj或外部文件的设置。
很方便:你可以在新模块里用严格模式,老代码不动也没事。
在<Nullable>里还能写啥
| 值 | 行为 |
|---|---|
|
全开:注解和警告都有 |
|
完全关闭null引用分析 |
|
只有警告,不强制注解 |
|
需要注解,但编译器不会警告 |
|
恢复到原始行为(比如全局设置) |
一般就用enable或disable。
3. 举个例子演示
NRT没开之前
// 老模式,NRT关着
string s = null; // 没人抱怨
Console.WriteLine(s.Length); // 危险! 可能抛NullReferenceException
NRT开了之后
// 新模式,NRT开着
string s = null; // 警告:可能赋值为null
Console.WriteLine(s.Length); // 警告:可能访问了null
现在IDE会开始标红有风险的地方,编译器也会提醒你:Dereference of a possibly null reference. (CS8602)
怎么修?
string? s = null;
if (s != null)
{
Console.WriteLine(s.Length);
}
这样你就明确告诉编译器:这个变量可能是null,编译器就满意了。
4. 如果项目是“老古董”风格咋办?
很多项目都是在null满天飞的年代写的。你一开NRT,就像请了个严厉的审查员,啥风险都给你报出来。
警告太多咋整?
别慌——这不是错误,只是提示。程序还是能编译的。
- 你可以只在新文件里开NRT。
- 慢慢整理代码:加?,做null检查,用!(后面会讲)。
- 记住:你越认真对待null,以后麻烦就越少。
兼容性和第三方库
- 开NRT不会影响代码运行时的行为,只是编译时多了分析。
- 老代码可能一下子冒出一堆警告。
- 如果你用的库没NRT注解,编译器会很谨慎地假设啥都可能是null。
GO TO FULL VERSION