c# - 如何在 C#7 中使用可为空的引用类型属性
问题描述
我有一个作为源代码分发的库,我不能强迫我的用户使用 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
您提到的东西。
推荐阅读
- php - 如何从数据库中的数值创建进度条?
- swift - 在 macOS 上为 Raspberry Pi 交叉编译 Swift 代码
- r - 如何使用 dplyr 在 R 中创建每月非累积小计?
- python - 我刚刚克隆的公司代码上没有找到页面 (404) 错误并且应该可以工作。代码有什么问题吗?
- c - 使用奇怪的权限打开创建文件
- reactjs - 有没有办法从材质表中的自定义操作手动触发 isLoading 动画?
- ios - 滚动时tableView的UIRefreshControl覆盖第一个单元格
- python - 如何在 google colab 上创建和使用自定义 OpenAI 健身房环境?
- json - 按索引对数组数组进行排序
- python - 分块处理大文件:seek 与 readline 不一致