Orw*_*wel 0 .net c# .net-core c#-8.0
我添加csproj以在C#8中启用Null引用类型:
<Nullable>enable</Nullable>
Run Code Online (Sandbox Code Playgroud)
此代码:
private static void Method()
{
var dictionary = new Dictionary<string, string>();
string value = string.Empty;
dictionary.TryGetValue("Key", out value);
}
Run Code Online (Sandbox Code Playgroud)
TryGetValue行带有警告:warning CS8600:将空文字或可能的空值转换为非空类型。
我不明白为什么。TryGetValue的签名为:
public bool TryGetValue(string key, [MaybeNullWhen(false)] out string value);
Run Code Online (Sandbox Code Playgroud)
该代码示例仅具有Non-Null引用。为什么会出现此错误?
如果"Key"
在字典中未找到,null
则将为分配一个值value
。但是,您已声明value
为string
,这意味着它不应包含null
。因此,编译器会向您发出警告。
最初分配string.Empty
给您的事实value
无关紧要-始终会被覆盖TryGetValue
(并且您应该得到另一个警告,指出该事实)。
您应声明value
为a string?
,以指示其值可能为null
。
请注意,编译器非常聪明。如果您写:
if (!dictionary.TryGetValue("Key", out string? value))
{
value = string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
那么编译器就会知道value
不能为null
,并且如果您尝试在其上调用方法,它也不会抱怨。
来自文档C# 编译器解释的空状态静态分析的属性。
在可空启用的上下文中,编译器执行代码的静态分析以确定所有引用类型变量的空状态:
- not-null:静态分析确定变量具有非空值。
- Maybe-null:静态分析无法确定为变量分配了非空值。
静态分析器认为变量可以是:
当一个不可为空的变量用属性MaybeNull修饰时,静态分析器认为该变量可能可以为空。
[return: MaybeNull]
static string Find(string key)
{
return key == "" ? null : key;
}
string value1 = Find("key"); // Warning CS8600 Converting null literal or possible null value to non-nullable type.
string? value2 = Find("key"); // No warning
var value3 = Find("key"); // The inferred type is 'string?'
Run Code Online (Sandbox Code Playgroud)
MaybeNullWhen属性类似,但静态分析器可以根据方法的结果处理检查。
static bool TryGetValue(string key, [MaybeNullWhen(false)] out string value)
{
if(key == "")
{
value = null;
return false;
}
value = "Foo";
return true;
}
string notnullable;
string value1;
if (TryGetValue("Key", out value1)) // Warning CS8600 Converting null literal or possible null value to non-nullable type.
notnullable = value1;
else
notnullable = value1; // Warning CS8600 Converting null literal or possible null value to non-nullable type.
string? value2;
if (TryGetValue("Key", out value2))
notnullable = value2;
else
notnullable = value2; // Warning CS8600 Converting null literal or possible null value to non-nullable type.
Run Code Online (Sandbox Code Playgroud)
我同意,这在这个例子中没有意义。但使用泛型方法时,您可以指定不可为 null 的类型,而该方法可以返回/设置 null:
[return: MaybeNull]
static T Find<T>(string key);
static bool TryGetValue<T>(string key, [MaybeNullWhen(false)] out T value)
Run Code Online (Sandbox Code Playgroud)