不可空的引用类型(再次)

时间:2011-10-10 13:02:15

标签: .net non-nullable

在.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
    }
} 

在我进一步调查之前,我想问一下是否有人知道这可能导致的任何问题?我无法想到任何事情。

1 个答案:

答案 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实例,无论实例是否是通过围绕你的围栏创建的 - 这并不比没有竖立围栏好多少首先。