我一直在 VS2008 上玩代码契约(Contract) (http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx)。
它们确实很好,并且提供了一个可靠的替代方法来替代方法内部的 if-then-throw 检查。
尽管如此,我一直希望它们能够满足我对不可空引用类型的强烈需求。
唉,据我所知,情况似乎并非如此。
这是我的理解:
像这样的东西在运行时仍然会引起问题:
MyClass a = null;<br/> a.ToString();
我仍然必须明确地编写支票,即使是以更简洁和流线型的方式。
除非您使用 VS Team System,否则您只能使用代码契约在运行时检查事物,在编译时没有任何好处。
这意味着当出现问题时,您仍然需要处理事情。
与处理一个简单的异常没有太大区别。即使使用 VSTS 静态分析也不如在运行时完成的那样好。
这是完全可以理解的,但这仍然是此功能用于运行时使用的另一个标志。
如果我错了,请纠正我,但据我所知,代码契约无法让我的生活更轻松,我的程序更健壮,就像不可为空的引用类型那样。
别误会,我并不讨厌代码契约。
它们是对整个框架的一个很好的增强。
只是如果这不能填补 C# 没有不可为空的引用类型留下的空白,在这一点上我恐怕什么也做不到。
你怎么看?
最佳答案
我认为您对此是正确的。编译时的不可空引用检查是我在代码契约中等待的 killer 级功能,但它实际上并不存在。
对于那些想知道这意味着什么的人,考虑与值类型的类比。它们最初不可为空,但现在如果您在类型名称后加上问号,它们就可以为空:
int? n;
为了保持一致性,如果引用类型也是如此,那将是理想的。但这会破坏所有现有的 C# 程序,因此不是一个选项。中研语Spec#他们使用感叹号后缀表示不可为空:
string! s = "Hello";
与普通值类型一样,编译器静态检查 string!
变量在初始化之前未在任何代码路径上使用(我相信 Spec# 要求声明和初始化发生在同样的声明)。
它还禁止将 null
分配给该变量。
当然,它禁止将普通的 string
赋值给 string!
。那么如何弥合这两种类型之间的差距呢?通过写支票:
string x = GetStringFromSomewhere();
if (x != null)
s = x; // okay because compiler sees null check
可悲的事实是,如果程序是正确的,大多数程序中的大部分引用变量很可能是不可空的。可空变量占少数。然而它们是默认设置。
关于c# - .NET 4.0 中的代码契约,非空引用类型的粉丝们不高兴吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1502858/