C# 为什么前置条件中提到的所有成员必须至少与方法本身一样容易访问?
我是代码契约的新手,文档中说前提条件中提到的所有成员必须至少与方法本身一样可访问,公共方法的前提条件中不能提到私有字段,因此下面的代码无法编译:C# 为什么前置条件中提到的所有成员必须至少与方法本身一样容易访问?,c#,.net,C#,.net,我是代码契约的新手,文档中说前提条件中提到的所有成员必须至少与方法本身一样可访问,公共方法的前提条件中不能提到私有字段,因此下面的代码无法编译: using System; using System.Diagnostics.Contracts; public class UseFulLibrary{ private static Item item = null; public static void Foo(Item newItem) { Contract.Requ
using System;
using System.Diagnostics.Contracts;
public class UseFulLibrary{
private static Item item = null;
public static void Foo(Item newItem) {
Contract.Requires(newItem != item); // doesn't compile
}
}
public class Item { }
但如果我们具备以下条件,则可以通过公共方法访问私有成员:
public class UseFulLibrary{
private static Item item = null;
public static void Foo(Item newItem) {
if (newItem != item) {
...
}
}
}
客户机当然可以调用
UseFulLibrary.Foo
方法,即使客户机无法在其端显式访问私有静态Item
字段,那么为什么先决条件需要这个不必要的条件呢?代码契约是。虽然名称空间在那里,代码可以编译,但是没有重写器,因此无法强制执行它们。您编写的合同代码编译为空。唯一的讨论是,在任何情况下,您在这里尝试做的事情都不能用代码契约来完成<代码>项是可写的,因此UseFullLibrary
中的任何方法都可以修改它。在编译时无法检查newItem
和item
是否不同。如果不能在编译时对代码契约进行评估,那么代码契约就毫无意义。如果(…)抛出新的ArgumentException(),它们与没有什么不同。事实上,第二次截取的行为与第一次截取的行为非常不同-它忽略重复项而不是抛出。在任何情况下,更改代码以避免编译无效操作更安全(可能更容易)。例如,在静态库本身中创建singleton实例,而不是从外部接受一个实例。将字段设置为只读。或者使用适当的单例实现—一个类中的公共静态属性,所有其他类都可以看到,该属性静态初始化或通过Lazy
初始化。假定您是Foo
的调用方,并且看到它具有“newItem!=item
”的先决条件,当item
的值对您隐藏时,如何确保不传入违反前提条件的内容!?开始出现在C#(模式匹配、开关表达式、记录)中的函数技术允许您编写甚至不允许出现“坏”情况的代码。通过记录,可以确保字段在初始化后不会更改。使用开关表达式,您可以确保不允许出现意外值(遗憾的是,仅限于某一点)。可空类型可以确保除非明确允许,否则任何null
s都不能潜行