我有一个作为源代码分发的库,我不能强制我的用户使用 C# 版本 8。
我仍然想改善使用 C# 8 和可空引用类型的用户的体验。
或者换句话说:我的库必须使用 C# 7 进行编译,但还包括有关可空引用类型的信息。
到目前为止我所做的是定义属性,MaybeNull
等,我的源文件以
#if (NETSTANDARD && !NETSTANDARD2_0 && !NETSTANDARD1_6) || (NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP2_1 && NETCOREAPP2_2)
#nullable disable warnings
#endif
我已经在属性、参数返回类型等上添加了属性
[return: MaybeNull]
public string Function([AllowNull) param) ...
这行得通,但因为我不能使用 ?
和 !
有几件事我还没有找到解决方案
-
Generics
,似乎没有办法用属性将泛型类型参数标记为可为空。即public async Task<string?> Method(KeyValuePair<string, string?> data)
的属性版本 - 属性和字段的属性在类内部被忽略(但在外部有效)
public class C {
[AllowNull, MaybeNull]
private string _field;
[AllowNull, MaybeNull]
public string Prop1 => _field; // CS8603, Possible null reference return
[AllowNull, MaybeNull]
public string Prop2 { get; set; }
public C() {
// CS8618, Non-nullable property 'Prop2' is uninitialized
// CS8618, Non-nullable field '_field' is uninitialized
}
}
- 警告本地人
string local = null;
等等
nullable disable warnings
为我的用户解决了最后两点,所以它并不重要,但泛型是一个问题,因为我有很多异步方法。 有没有办法在不使用 ?
的情况下在泛型中标记可为空的引用类型? ?
最佳答案
您可以使用 C# 8 编译您的库,并让其他人使用来自 C# 7(或更早版本)的二进制文件。限制因素不是语言而是框架(除非他们使用较早的编译器编译您的源代码)。
NRT 注释使用在生成的程序集中自动定义的属性。您通常看不到这些,它们是按名称而不是 Type
匹配的,这意味着您可以使用来自多个程序集的注释,即使它们具有不同的注释类型(具有相同的、众所周知的名)。
这与 MaybeNull
和 NotNullWhen
等属性不同,它们不是由编译器生成的,但是也与全名匹配,这意味着您可以自己定义它们或使用诸如 Nullable
之类的库。
综上所述,您应该能够使用 ?
、!
并避免使用 #if
/#endif
你提到的东西。
关于c# - 如何在 C#7 中使用可空引用类型属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60409751/