为此生成的IL:
Console.WriteLine("{0}, {1}", default(Guid), Guid.Empty);
是:
.locals init (
[0] valuetype [mscorlib]System.Guid CS$0$0000)
L_0000: nop
L_0001: ldstr "{0}, {1}"
L_0006: ldloca.s CS$0$0000
L_0008: initobj [mscorlib]System.Guid
L_000e: ldloc.0
L_000f: box [mscorlib]System.Guid
L_0014: ldsfld valuetype [mscorlib]System.Guid [mscorlib]System.Guid::Empty
L_0019: box [mscorlib]System.Guid
L_001e: call void [mscorlib]System.Console::WriteLine(string, object, object)
它相当于:
Guid CS$0$0000 = new Guid();
Console.WriteLine("{0}, {1}", CS$0$0000, Guid.Empty);
代码契约直接在IL上工作,因此它认为您编写了类似于第二个版本的东西。重写器表示不允许在协定之前为变量赋值,因此它给出了一个错误。
然而,这很奇怪,因为尽管这不起作用:
var x = new Guid();
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == x);
确实如此,但它显然是一个“不变量前的赋值”!
var x = Guid.Empty;
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == x);
我认为他们实际上修改了检查程序以允许这样的分配(为了使用方便),但他们不允许所有的情况…我不知道这是不是有意的。
我会在
Code Contracts forum
,可能是一个错误。