c# - .NET 4.0 中的代码契约,非空引用类型的粉丝们不高兴吗?

标签 c# .net .net-4.0 c#-4.0 code-contracts

我一直在 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

可悲的事实是,如果程序是正确的,大多数程序中的大部分引用变量很可能是不可空的。可空变量占少数。然而它们是默认设置。

Another bad idea from the 1960s !

关于c# - .NET 4.0 中的代码契约,非空引用类型的粉丝们不高兴吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1502858/

相关文章:

javascript - 如何访问 js/jquery 中的用户控件值

c# - 不同地区不同认证方式

c# - 如何加密/解密以存储敏感数据(ASP.NET Web API 项目)

c# - Entity Framework 5 - 派生类的基于枚举的鉴别器

wpf - Windows 文件名中不允许使用哪些字符以及如何限制它们在 C# 中键入

c# - 从具有 FaultException 的 WCF Web 服务中消除天妇罗

c# - 列 ID 在规范中出现多次

c# - 枚举声明中不必要的逗号

c# - 单个对象作为报表查看器的数据源

c# - 如何在 C# 中使用反射检查集合类型属性的相等性