Why contract is malformed when using default(Type)?

When compiling code which uses code contracts, I have a very strange error I don't understand.

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

fails with the following error:

Malformed contract. Found Invariant after assignment in method '.ObjectInvariant'.

If the code is modified like this:

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

it compiles well.

What's wrong with my default(Guid)?

9
задан Arseni Mourzenko 29 August 2010 в 12:23
поделиться

1 ответ

Сгенерированный для этого 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);

это работает, но это явно "назначение перед инвариантом"!

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

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

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

6
ответ дан 3 November 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: