2010-09-04 5 views
7

Der folgende Code gibt mir die Warnung Contract class 'FooContracts' should be an abstract class. Von allen Beispielen, die ich online gelesen habe (z. B. http://www.infoq.com/articles/code-contracts-csharp), sollte dies funktionieren (vermutlich ohne Compiler-Warnungen).Vertragsklasse sollte eine abstrakte Klasse sein

[ContractClass(typeof(FooContracts))] 
public interface IFoo { 
    void Bar(string foo); 
} 

[ContractClassFor(typeof(IFoo))] 
internal sealed class FooContracts : IFoo { 
    void IFoo.Bar(string foo) { 
    Contract.Requires(foo != null); 
    } 
} 

Ich bin in Visual Studio 2010, mit den folgenden Einstellungen im Code Contracts Abschnitt der Eigenschaften des Projektes:

  • Perform Runtime Vertrag prüfen (auf Full)
  • Perform Static Vertrag prüfen (unter Static Checking)
  • Einchecken im Hintergrund

Ich habe auch das Kompilierungssymbol CONTRACTS_FULL definiert, um ReSharper zum Schweigen zu bringen.

Fehle ich etwas, um dieses kompilieren ohne Warnungen zu machen?

Antwort

9

Abschnitt 2.8 des code contracts manual heißt es ausdrücklich, dass es sich um eine abstrakte Klasse sein sollte:

Die Werkzeuge erwarten, dass der Vertrag Klasse abstrakt ist und implementiert die Schnittstelle ist Verträge für die Bereitstellung.

+1

huh. Danke für den Link. diese Tatsache wurde in keinem von mir gefundenen Beispielcode erwähnt oder demonstriert. – tmont

3

Wahrscheinlich ist der InfoQ-Artikel, auf den Sie verweisen, falsch. Es basiert auf einer "Early Access" -Version von C# in Depth, so dass sich die Code-Contracts-Implementierung wahrscheinlich zwischen dem Zeitpunkt, zu dem das Kapitel/Artikel ursprünglich geschrieben wurde, und .NET 4 geändert hat.

sollte der folgende Code arbeiten:

[ContractClass(typeof(FooContracts))] 
public interface IFoo { 
    void Bar(string foo); 
} 

[ContractClassFor(typeof(IFoo))] 
internal abstract class FooContracts : IFoo { 
    void IFoo.Bar(string foo) { 
    Contract.Requires(foo != null); 
    } 
} 

Den Vertrag Klasse abstrakt sein muss.

+0

Aber die Klasse abstrakt machen bedeutet, dass Sie es nicht neu erstellen können, nachdem Sie die Schnittstelle implementieren :(Irgendwelche Alternative um diese? Andere, die eine neue konkrete Klasse erbt, die von der abstrakten Klasse erbt? – bitek

+1

@MnemonicFlow Sie sollten keine Instanzen von erstellen Die Vertragsklasse ist sowieso nur für die Code Contracts-Engine vorgesehen. – piedar

Verwandte Themen