.NET 4.0 中的代码契约,对于不可为空引用类型的粉丝来说没有乐趣吗?
我一直在 VS2008 上使用代码契约 (http://msdn.microsoft. com/en-us/devlabs/dd491992.aspx)。
它们确实很好,并且为方法内部的 if-then- throw 检查提供了可靠的替代方案。
尽管如此,我一直希望它们能够满足我对不可空引用类型的强烈需求。
唉,据我所知,情况似乎并非如此。
这就是我的理解:
这样的事情仍然会在运行时引起问题:
<代码> MyClass a = null;
a.ToString();我仍然必须显式地编写检查,即使以更简洁和简化的方式。
除非您使用 VS Team System,否则您只能使用代码契约在运行时检查内容,在编译时没有任何好处。
这意味着当出现问题时你仍然必须处理事情。
与处理简单的异常没有太大区别。即使使用 VSTS,静态分析也不像运行时那样好。
这是完全可以理解的,但这仍然是该功能适用于运行时使用的另一个标志。
如果我错了,请纠正我,但从我看来,代码契约不可能让我的生活更轻松,让我的程序更健壮,就像不可为空的引用类型那样。
不要误会我的意思,我并不不喜欢代码契约。
它们对整个框架来说是一个非常好的增强。
只是,如果这不能填补 C# 由于没有不可为空引用类型而留下的空白,那么目前恐怕什么都无法填补。
你怎么认为?
I've been playing with Code Contracts on VS2008 (http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx).
They surely are nice and provide a solid alternative to if-then-throw checks inside methods.
Nonetheless I've been hoping that they could satisfy the need that I strongly feel for non-nullable reference types.
Alas, from what I could see this doesn't seem to be the case.
This is what I understood:
Something like this will still cause issues at runtime:
MyClass a = null;
a.ToString();I still have to explicitly write checks, even if in a more concise and streamlined way.
Unless you use VS Team System you can only use code contracts to check things at runtime, no benefits at compile time.
Meaning that you still have to handle things when something goes wrong.
Not much different from handling a simple exception.Even with VSTS static analysis isn't as a good as the one done at runtime.
This is perfectly understandable, still it's another sign that this feature is meant for runtime usage.
Please correct me if I'm wrong but from what I see there's no way Code Contracts can make my life easier, and my programs more robust, like non-nullable reference types would.
Don't get me wrong, I don't dislike code contracts.
They are a very nice enhancement to the whole framework.
It's just that if this doesn't fill the gap that C# leaves by not having non-nullable reference types, at this point I'm afraid that nothing will.
What do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为你对此是正确的。编译时不可为空的引用检查是我在代码契约中等待的杀手级功能,但它实际上并不存在。
对于那些想知道这意味着什么的人,请考虑与值类型的类比。它们最初不可为空,但现在如果您在类型名称后面加上问号,则可以为空:
为了保持一致性,如果引用类型也是如此,那将是理想的选择。但这会破坏所有现有的 C# 程序,因此不是一个选择。在研究语言 Spec# 中,他们使用感叹号后缀来表示不可为空:
与普通值类型一样,编译器静态检查
string!
变量在初始化之前是否未在任何代码路径上使用(我相信 Spec# 要求声明和初始化发生在相同的声明)。它还禁止将
null
分配给该变量。当然,它禁止将普通
字符串
分配给字符串!
。那么如何弥合这两种类型之间的差距呢?通过编写检查:可悲的事实是,如果程序正确,大多数程序中的大多数引用变量可能都是不可为空的。可空变量只占少数。然而它们是默认的。
20世纪60年代的另一个坏主意!
I think you're correct about this. Non-nullable reference checking at compile time was the killer feature I was waiting for in Code Contracts, and it isn't really there.
For those wondering what this means, consider an analogy with value types. They were not nullable originally, but now they are if you put a question mark after the type name:
For consistency it would be ideal if the same was true of reference types. But that would break all existing C# programs and so isn't an option. In the research language Spec# they went with using an exclamation mark suffix to mean non-nullable:
As with ordinary value types, the compiler statically checks that a
string!
variable is not used on any code path before it has been initialised (I believe Spec# requires declaration and initialization to occur in the same statement).It also bans the assignment of
null
to that variable.And of course, it bans the assignment of an ordinary
string
to astring!
. So how do bridge the gap between the two kinds of type? By writing a check:The sad truth is that the majority of reference variables in most programs are likely to be non-nullable if the program is correct. Nullable variables are in the minority. And yet they are the default.
Another bad idea from the 1960s!
我不确定“不可为空引用类型”解决了什么问题。好的,所以这段代码抛出异常的可能性要小得多:-
但是它是否可能是正确,因为它不可为空?
a
的初始值是多少?可能是该类型的一些默认“空”实例。在这种情况下,是不是更有可能使事情变得更难以调试,因为应该分配值的值却没有分配。仅具有一些默认行为而不是引发异常听起来不像我想要的。I'm not sure what problem is solved by "non-nullable reference types". Ok so this code is much less likely to throw an exception:-
However is it anymore likely to be correct because a it non-nullable? What would be the initial value of
a
? Probably some default "Empty" instance of the type. In that case isn't it more likely to make things more difficult to debug since values which should've been assigned a value haven't. Just having some default behaviour rather than causing an exception doesn't sound like something I'd want.我认为不可空引用类型的概念对于 ORM 生成的映射到数据库字段的属性非常有用。通常,您无法从属性(通常为字符串类型)判断基础字段是否可为空。对于可空值类型,您只需查找问号即可。
除了明显的 foo 之外,我不太担心静态检查! = 空;失败了,但我认为智能感知作为可变意图的提示非常有用。
I think the concept of a non-nullable reference type would be really useful for ORM generated properties that map to database fields. Often you can't tell from the property (usually type string) whether the underlying field is nullable or not. With nullable value types you can, just by looking for the question mark.
I'm not too worried about static checking, apart from obvious foo! = null; failing, but the intellisense would be very useful as a hint to variable intent, I think.
2017 年更新(8 年后),虽然不可空引用类型仍然不存在...可空引用类型可能。
Mads Torgersen(微软的 C# 语言 PM)确实提到了它在此推文中:
“介绍 Nullable 对此进行了详细介绍C# 中的引用类型”,以及此视频中的“C# 7.1 提供的新功能”和7.2”。
这仍然是一个原型,最终可能会(或不会)出现在该语言中。
请参阅“C# 可空引用类型预览”了解更多信息。
Update 2017 (8 years later), while Non-nullable reference type is still not there... nullable reference type might.
Mads Torgersen (C# Language PM at Microsoft) does mention it in this tweet:
This is detailed in "Introducing Nullable Reference Types in C#", and in this video "new features available C# 7.1 and 7.2".
This is still a prototype, and might end up (or not) in the language.
See more at "The C# Nullable Reference Types Preview".
您可以使用像 string.empty 这样的默认值,而不是使用 null ,不需要 null
rather than using null you can use a default like string.empty there is no need for nulls