.NET 4.0中的代码契约,对于非可空引用类型的粉丝来说,没有什么乐趣?

Rob*_*van 9 .net c# .net-4.0 code-contracts c#-4.0

我一直在玩VS2008上的Code Contracts(http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx).
它们肯定很好,并为方法中的if-then-throw检查提供了一个可靠的替代方案.

尽管如此,我一直希望他们能够满足我对非可空引用类型的强烈感受.
唉,从我所看到的情况来看似乎并非如此.
这就是我的理解:

  • 这样的事情仍会在运行时引起问题:
    MyClass a = null;
    a.ToString();

  • 我仍然必须明确地写支票,即使是以更简洁和简化的方式.

  • 除非您使用VS Team System,否则您只能使用代码契约在运行时检查事物,在编译时没有任何好处.
    这意味着当出现问题时你仍然需要处理事情.
    与处理简单异常没什么不同.

  • 即使使用VSTS,静态分析也不如在运行时完成的那样好.
    这是完全可以理解的,但这仍然是该功能用于运行时使用的另一个标志.

如果我错了,请纠正我,但从我看到的情况来看,Code Contracts无法使我的生活变得更轻松,而且我的程序更加健壮,就像非可空引用类型一样.

不要误会我的意思,我不喜欢代码合同.
它们是整个框架的一个非常好的增强.
只是如果这没有填补C#通过没有非可空引用类型而离开的空白,此时我担心什么都不会.
你怎么看?

Dan*_*ker 20

我认为你这是正确的.编译时不可空的引用检查是我在代码契约中等待的杀手级功能,并不是真的存在.

对于那些想知道这意味着什么的人,可以考虑与价值类型进行类比.它们最初不可为空,但现在它们就是在类型名称后面加上一个问号:

int? n;
Run Code Online (Sandbox Code Playgroud)

为了保持一致性,如果参考类型也是如此,那将是理想的.但这会破坏所有现有的C#程序,因此不是一种选择.在研究语言Spec#中,他们使用感叹号后缀表示不可为空:

string! s = "Hello";
Run Code Online (Sandbox Code Playgroud)

与普通值类型一样,编译器string!在初始化之前静态检查变量是否在任何代码路径上都没有使用(我相信Spec#需要在同一语句中进行声明和初始化).

它还禁止分配null给该变量.

当然,它禁止将普通人分配stringstring!.那么如何弥合这两种类型之间的差距呢?通过写支票:

string x = GetStringFromSomewhere();

if (x != null)
    s = x; // okay because compiler sees null check
Run Code Online (Sandbox Code Playgroud)

可悲的事实是,如果程序正确,大多数程序中的大多数参考变量可能是不可空的.可空变量属于少数.但它们是默认值.

20世纪60年代的另一个坏主意!