C# 从另一个泛型方法调用MaybeNull泛型方法
我有这样一个扩展方法:C# 从另一个泛型方法调用MaybeNull泛型方法,c#,generics,c#-8.0,nullable-reference-types,C#,Generics,C# 8.0,Nullable Reference Types,我有这样一个扩展方法: [return: MaybeNull] public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) where TKey : notnull where TValue : notnull { if (dictionary.TryGetValue(key, out TValue value))
[return: MaybeNull]
public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : notnull
where TValue : notnull {
if (dictionary.TryGetValue(key, out TValue value)) return value;
else return default!;
}
我对C#8.0可空引用类型非常陌生,尤其是涉及泛型的引用类型。我还缺什么东西来让它工作吗?在没有编译器警告的情况下,感觉它违背了使用C#8.0可空类型的目的。我陷入了一种错误的安全感,我不可能错过NullReferenceException,特别是当Visual Studio向我保证“s2在这里不是空的”时,尽管它绝对是空的。这在新版本的编译器(仍然是C#8,只是一个新的编译器)中得到了改进。如果您使用较新的Visual Studio,您将拥有较新的编译器 以下是您的示例: 有两项改进:
代码>默认值
,因为分析现在考虑了GetValueOrDefault
上的MaybeNull
属性我认为,在您的示例中,
TKey
和TValue
的原因可能是值类型的引用。编译器根本不知道类型本身是否可以在运行时,这是真的;如果我改为使用where TValue:class
,并将返回类型设置为TValue?
,编译器会很好地警告我。但TValue并不总是一个类;有时我的IDictionary上有值类型。您可以参考这一点,尤其是notnull
通用约束和T?
部分的问题。您还可以查看现有线程,如或。似乎,MaybeNull
是这里的最佳选择,您应该使用它来帮助编译器识别正确的返回类型将Visual Studio升级到16.5.4,并确认它修复了问题。非常感谢!
public static TValue SomeOtherMethod<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : notnull
where TValue : notnull
=> dictionary.GetValueOrDefault(key); // No warning this could be null
...
var dictionary = new Dictionary<string, string>() {
["hello"] = "world"
};
string s1 = dictionary.GetValueOrDefault("foo"); // Compiler warning
string s2 = dictionary.SomeOtherMethod("foo"); // No compiler warning
int s2Len = s2.Length; // Visual Studio states "s2 is not null here", even though it absolutely is!