我添加csproj以在C#8中启用Null引用类型:
<Nullable>enable</Nullable>
此代码:
private static void Method()
{
var dictionary = new Dictionary<string, string>();
string value = string.Empty;
dictionary.TryGetValue("Key", out value);
}
TryGetValue行带有警告: 警告CS8600:将空文字或可能的空值转换为非空类型。
我不明白为什么。 TryGetValue的签名是:
public bool TryGetValue(string key, [MaybeNullWhen(false)] out string value);
该代码示例仅具有Non-Null引用。为什么会出现此错误?
答案 0 :(得分:6)
如果在字典中未找到import math
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def std_dev(persons):
persons=Person
mean = sum(persons)*1.0/len(persons)
length = len(persons)
mean = mean(persons)
total_sum = 0
for i in range(length):
total_sum += (persons[i]-mean)**2
square_root = total_sum*1.0/length
return math.sqrt(square_root)
,则将"Key"
的值分配给null
变量。但是,您已将value
声明为value
,这意味着它不应包含string
。因此,编译器会向您发出警告。
您最初将null
分配给string.Empty
的事实并不重要-这将始终被value
覆盖(并且您应该得到另一个警告,指出这一点)。
您应将TryGetValue
声明为value
,以指示其值可能为string?
。
请注意,编译器非常聪明。如果您写:
null
然后编译器知道if (!dictionary.TryGetValue("Key", out string? value))
{
value = string.Empty;
}
不能为value
,并且如果您随后尝试在其上调用方法,它也不会抱怨。
答案 1 :(得分:3)
canton7的答案是正确的(+1)。
这不是解释,而是一种解决方法:
您可以像这样向Dictionary<TVey, TValue>
添加扩展方法:
public static bool TryGetValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue @default, out TValue @value) where TKey : notnull
{
var result = dictionary.TryGetValue(key, out var val);
@value = result ? val : @default;
return result;
}
然后您可以像这样使用它:
private static void Method()
{
var dictionary = new Dictionary<string, string>();
/// populate dictionary here...
dictionary.TryGetValue("Key", string.Empty, out var value);
}
这应该使您能够将value
保留为不可为空的字符串。