从另一个泛型方法调用 MaybeNull 泛型方法
Calling a MaybeNull generic method from another generic method
我有这样的扩展方法:
[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!;
}
这很好用。如果我调用它期望一个非空值,编译器会警告我结果可能为空,这正是我想要的。
但是,如果我有另一个调用 GetValueOrDefault
的方法,而我忘记添加 [return: MaybeNull]
,编译器根本不会警告我。这是一个复杂的例子来解释我的问题:
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!
我对 C# 8.0 可为 null 的引用类型还很陌生,尤其是涉及泛型时。有什么我想念的吗?没有编译器警告,感觉它违背了使用 C# 8.0 可空类型的目的。我陷入了一种错误的安全感,我不可能错过 NullReferenceException,尤其是当 Visual Studio 让我放心 "s2 is not null here" 时,尽管它绝对是。
这在较新版本的编译器中得到了改进(仍然是 C# 8,只是较新的编译器)。如果您使用更新的 Visual Studio,您将拥有更新的编译器。
这是你的例子:
有两个改进:
- 您不需要
!
default
,因为分析现在尊重 GetValueOrDefault
上的 MaybeNull
属性。
- 您现在收到警告 CS8603(可能为空引用 return),您之前指出您没有收到警告但理应收到警告。
我有这样的扩展方法:
[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!;
}
这很好用。如果我调用它期望一个非空值,编译器会警告我结果可能为空,这正是我想要的。
但是,如果我有另一个调用 GetValueOrDefault
的方法,而我忘记添加 [return: MaybeNull]
,编译器根本不会警告我。这是一个复杂的例子来解释我的问题:
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!
我对 C# 8.0 可为 null 的引用类型还很陌生,尤其是涉及泛型时。有什么我想念的吗?没有编译器警告,感觉它违背了使用 C# 8.0 可空类型的目的。我陷入了一种错误的安全感,我不可能错过 NullReferenceException,尤其是当 Visual Studio 让我放心 "s2 is not null here" 时,尽管它绝对是。
这在较新版本的编译器中得到了改进(仍然是 C# 8,只是较新的编译器)。如果您使用更新的 Visual Studio,您将拥有更新的编译器。
这是你的例子:
有两个改进:
- 您不需要
!
default
,因为分析现在尊重GetValueOrDefault
上的MaybeNull
属性。 - 您现在收到警告 CS8603(可能为空引用 return),您之前指出您没有收到警告但理应收到警告。