2013-07-24 22 views
5

Próbowałem poniższy kod, żeby umożliwić jakieś not null Sprawdzanie pobranych podmiotów, aby zapewnić ich istnieć przed jakiejś konkretny biznes:CodeContracts „niezbędne” zrozumienie

protected T GetRequired<T>(object id) 
    where T : EntityObject 
{ 
    var obj = Get<T>(id); 
    Contract.Requires<ArgumentNullException>(obj != null); 
    return obj; 
} 

Ale w czasie kompilacji dostaję :
After contract block, found use of local variable 'obj' defined in contract block

używam Contract.Requires w niewłaściwy sposób?

Odpowiedz

6

Czy używam Contract.Requires w niewłaściwy sposób?

Tak, jesteś. Contract.Requires jest o określeniu warunków wstępnych dla metody (lub właściwości). Są to warunki, które muszą być spełnione, aby wywołanie metody było kontynuowane, w przeciwnym razie wystąpi naruszenie umowy.

Rzućmy okiem na kodzie:

var obj = Get<T>(id); 
Contract.Requires<ArgumentNullException>(obj != null); 

Tutaj jesteś próbuje go używać, aby zapewnić, że coś jest prawdą po metoda zakończeniu wykonywania (w tym przypadku Get metoda). To byłby postcondition i za to należy użyć Contract.Ensures w ciele Get:

protected T Get<T>(object id) { 
    Contract.Ensures(Contract.Results<T>() != null); 
    // get and return result 
} 

Wreszcie ten błąd kompilatora

Po bloku zamówienia, znalazł zastosowanie zmiennej lokalnej obj określonej w blok kontraktowy

Ta wiadomość wynika z faktu, że nie można używać Contract s po e blok kontraktu, a blok kontraktu pojawia się u góry korpusu metody tylko.

3

Wydaje się, że staramy się robić kilka rzeczy naraz tutaj:

Contract.Requires należy stosować od parametru wejściowego bezpośrednio, na przykład jeśli id nigdy nie powinno być puste, a następnie zrobić tak:

Contract.Requires<ArgumentNullException>(id != null); 

Ponadto, wydaje się, że chcesz, aby zagwarantować, że wynik nie jest null. Czy to tak:

Contract.Ensures(obj != null); 

Podobnie, dodatkowe kontrakty mogą być kontrolowane przez metodę pomocnika (Get).