Почему контракт искажен при использовании default (Тип)? - PullRequest
9 голосов
/ 30 августа 2010

При компиляции кода, использующего кодовые контракты, у меня возникает очень странная ошибка, которую я не понимаю.

[ContractInvariantMethod]
private void ObjectInvariant()
{
    Contract.Invariant(
        this.isSubsidiary ||
        this.parentCompanyId == default(Guid));
}

завершается с ошибкой:

Неправильный контракт. Найден инвариант после присваивания в методе ' .ObjectInvariant'.

Если код изменен следующим образом:

[ContractInvariantMethod]
private void ObjectInvariant()
{
    Contract.Invariant(
        this.isSubsidiary ||
        this.parentCompanyId == Guid.Empty);
        // Noticed the Guid.Empty instead of default(Guid)?
}

хорошо компилируется.

Что не так с моим default(Guid)?

1 Ответ

6 голосов
/ 30 августа 2010

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 работает непосредственно наИЛ, так что кажется, что ты написал что-то вроде второй версии.Переписчик говорит, что вам не разрешено присваивать переменные до заключения контракта, поэтому выдает ошибку.

Однако это странно, потому что пока это не работает:

var x = new Guid();
Contract.Invariant(
    this.isSubsidiary ||
    this.parentCompanyId == x);

это так, но это явно «задание перед инвариантом»!

var x = Guid.Empty;
Contract.Invariant(
    this.isSubsidiary ||
    this.parentCompanyId == x);

Я думаю, что они на самом деле изменили средство проверки, чтобы разрешить некоторые назначения, подобные этому (для простоты использования), но они не имеютЯ допускаю все случаи ... независимо от того, предназначено ли это или нет, я не знаю.

Я бы сообщил об этом на форуме Code Contracts , это может быть ошибка.

...