在编译使用代码契约的代码时,我有一个非常奇怪的错误,我不明白。
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == default(Guid));
}
因以下错误而失败:
合同格式错误。在方法'< ProjectName> .ObjectInvariant'中分配后找到不变量。
如果代码修改如下:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == Guid.Empty);
// Noticed the Guid.Empty instead of default(Guid)?
}
它汇编得很好。
我的default(Guid)
出了什么问题?
答案 0 :(得分:6)
为此生成的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);
Code Contracts直接在IL上工作,所以它认为你写的是第二个版本。重写者说你不允许在合同之前分配变量,因此它会给出错误。
然而,这很奇怪,因为虽然这不起作用:
var x = new Guid();
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == x);
这样做,但显然是“在Invariant之前的任务”!
var x = Guid.Empty;
Contract.Invariant(
this.isSubsidiary ||
this.parentCompanyId == x);
我认为他们实际上修改了检查器以允许这样的一些任务(为了便于使用),但是他们不允许所有情况......这是否有意为我所知。
我会在Code Contracts forum上报告,这可能是一个错误。