2010-08-29 23 views
9

Kod sözleşmelerini kullanan kodları derlerken, anlayamadığım çok tuhaf bir hatam var.Varsayılan (Tip) kullanıldığında neden sözleşme yanlış biçimlendiriliyor?

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

aşağıdaki hata nedeniyle başarısız: kodu şöyle değiştirilir

Malformed contract. Found Invariant after assignment in method '<ProjectName>.ObjectInvariant'.

ise:

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

iyi derler.

default(Guid) benim sorunum nedir?

+0

Bildiğim kadarıyla: public static readonly Guid Empty; ve varsayılan (Guid) veya yeni Guid() aynı şey Burada neden çalışmıyor bilmiyorum. – abhishek

+0

Ben de buna rastladım. Merakla varsayılan (int) aynı etkiye sahip değildir. –

+0

@Can Gencer: Bence Porges'in cevabını okursanız bu beklenir. Varsayılan (Guid) 'için, IL, Guid = Guid()' e karşılık gelir, böylece bir yönteme (yapıcı) bir çağrı vardır. Bunun yerine, 'default (int)' 'int şey = new int()' ile uyuşmayacak, anlam ifade etmiyor. Bu yüzden 'int' durumunda derleyici şikâyetçi değildir. –

cevap

6

IL bunun için oluşturulan: böyle bir şey tekabül

.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); 

Kod Sözleşmeleri IL üzerinde doğrudan çalışır, bu yüzden düşünür

Console.WriteLine("{0}, {1}", default(Guid), Guid.Empty); 

olduğunu İkinci versiyon gibi bir şey yazdınız. Yeniden yazma, sözleşmelerden önce değişkenlere atanmanıza izin verilmediğini söylüyor, bu yüzden bir hata veriyor.

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

bunu yapar, ama açıkça bir "Değişmeyen önce atama" dir: Bu işe yaramazsa, çünkü süre

Ancak bu, tuhaf!

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

Ben aslında (kullanım kolaylığı için) bu gibi bazı düzenlemeleri sağlamaktır denetleyicisi modifiye düşünüyorum, ama hepsi durumlarda izin verilmez ki ... Bu is bilgim dışında amaçlanan olup olmadığını.

Bunu Code Contracts forum numaralı telefondan bildirebilirim, bu bir hata olabilir.

İlgili konular