c# - 为 DTO 使用可空引用类型的最佳实践
问题描述
我有一个 DTO,它是通过从 DynamoDB 表中读取来填充的。说它目前看起来像这样:
public class Item
{
public string Id { get; set; } // PK so technically cannot be null
public string Name { get; set; } // validation to prevent nulls but this doesn't stop database hacks
public string Description { get; set; } // can be null
}
是否有任何最佳实践来解决这个问题?我宁愿避免使用非无参数构造函数,因为它与 Dynamo SDK(以及其他)中的 ORM 很不符。
写起来对我来说似乎很奇怪,public string Id { get; set; } = "";
因为这永远不会发生,因为这Id
是一个 PK 并且永远不能为空。""
即使它以某种方式发生了又有什么用呢?
那么这方面有什么最佳实践吗?
- 我是否应该将它们全部标记为
string?
说它们可以为空,即使有些永远不应该。 - 我是否应该初始化
Id
并Name
使用,""
因为它们永远不应该为空,这表明了意图,即使""
永远不会被使用。 - 以上的一些组合
请注意:这是关于 C#8可空引用类型如果您不知道它们是什么最好不要回答。
解决方案
作为一种选择,您可以将default
文字与null forgiving operator
public class Item
{
public string Id { get; set; } = default!;
public string Name { get; set; } = default!;
public string Description { get; set; } = default!;
}
由于您的 DTO 是从 DynamoDB 填充的,因此您可以使用MaybeNull/NotNull
后置条件属性来控制可空性
MaybeNull
不可为空的返回值可能为空。NotNull
可为空的返回值永远不会为空。
但是这些属性只影响使用它们注释的成员的调用者的可空分析。通常,您将这些属性应用于方法返回、属性和索引器 getter。
因此,您可以考虑所有属性不可为空的并用MaybeNull
属性装饰它们,表明它们返回可能的null
值
public class Item
{
public string Id { get; set; } = "";
[MaybeNull] public string Name { get; set; } = default!;
[MaybeNull] public string Description { get; set; } = default!;
}
以下示例显示了更新Item
类的用法。如您所见,第二行没有显示警告,但第三行显示
var item = new Item();
string id = item.Id;
string name = item.Name; //warning CS8600: Converting null literal or possible null value to non-nullable type.
或者您可以将所有属性设为可为空的,并用于NoNull
指示返回值不能为null
(Id
例如)
public class Item
{
[NotNull] public string? Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
}
警告将与前面的示例相同。
输入参数、属性和索引器设置器也有AllowNull/DisallowNull
前置条件属性,以类似的方式工作。
AllowNull
不可为空的输入参数可能为空。DisallowNull
可为空的输入参数永远不应为空。
我认为它不会对您有所帮助,因为您的类是从数据库中填充的,但是您可以使用它们来控制属性设置器的可空性,例如第一个选项
[MaybeNull, AllowNull] public string Description { get; set; }
而对于第二个
[NotNull, DisallowNull] public string? Id { get; set; }
推荐阅读
- karate - 使用 Runner.parallel 时未运行的功能
- amazon-web-services - 在 EMR 中添加 S3 同步步骤
- spring-integration - jpa入站通道适配器输出问题
- apache - 需要从 apache 访问日志中获取唯一的 url - 以及它们的计数
- php - php guzzle 一个简单的 R 包函数的 OpenCPU POST 请求在执行期间卡住了
- spring - 为什么资源文件没有在spring-mvc中加载
- python - 如何在pyspark数据框中的每个窗口中检索唯一值
- javascript - 如何将json文件的结果放入变量javascript中
- javascript - 如何修复 CORS 错误以提供虚假开发数据
- python - 如何从看门狗的事件处理程序中获取返回值