在.NET中支持非可空引用类型时存在很多问题。最大的希望是代码合同,但它仅限于对预算有限的人进行运行时检查。
至于代码合约以外的其他方法,几年前Jon Skeet写了一篇blog post,其中一位评论者提供了一个有用的外观NonNull struct,修改了IL以禁用默认值构造函数。这似乎是一种很好的方法,我可以想象将它扩展为提供各种不可为空的microtypes。 IL操作可以是由结构上的属性触发的构建后步骤,例如。
//Microtype representing a non-zero age, so we want to disable the default ctor
[NoDefaultConstructor]
public struct Age
{
public Age(int age)
{
// Implementation (including validation) elided
}
}
在我进一步调查之前,我想问一下是否有人知道这可能导致的任何问题?我无法想到任何事情。
答案 0 :(得分:6)
这很容易被打败 - 运行时不会尝试在每个场景中调用结构的无参数构造函数(如果存在)。
特别是,在创建struct-type数组时不会调用它。
Age[] ages = new Age[3];
// This guy skips your "real" ctor as well as the "invalid" parameterless one.
Age age = ages[0];
...或default(structType)
表达式:
// Invalid state here too.
Age age = default(Age);
从Jon Skeet的empirical research到这些东西,这里是一个不调用构造函数的其他操作的列表:
- 只声明一个变量,无论是本地变量,静态变量还是实例
- 拳击
- 在通用方法中使用
default(T)
- 在通用方法中使用
new T()
现在让你离开的情况是你必须以某种方式测试每个Age
实例,无论实例是否是通过围绕你的围栏创建的 - 这并不比没有竖立围栏好多少首先。