Zakładamy następujący kod:Niepotwierdzone Upewnić się, że odwołuje się do innej właściwości w połączeniu z interfejsem
[ContractClass(typeof(ICC4Contract))]
public interface ICC4
{
bool IsFooSet { get; }
string Foo { get; }
}
public class CC4 : ICC4
{
private string _foo;
public bool IsFooSet { get { return Foo != null; } }
public string Foo { get { return _foo; } }
}
[ContractClassFor(typeof(ICC4))]
public abstract class ICC4Contract : ICC4
{
public bool IsFooSet
{
get
{
Contract.Ensures((Contract.Result<bool>() && Foo != null)
|| !Contract.Result<bool>());
return false;
}
}
public string Foo
{
get
{
Contract.Ensures((Contract.Result<string>() != null && IsFooSet)
|| !IsFooSet);
return null;
}
}
}
Kontrakty próbują powiedzieć:
IsFooSet
powrócitrue
jeśliFoo
nie jestnull
.Foo
nie zwracanull
, jeśliIsFooSet
zwracatrue
.
To prawie działa.
Jednak otrzymuję komunikat "gwarantuje, że nie został sprawdzony" na return _foo;
, ponieważ kontroler nie zdaje sobie sprawy, że Foo
będzie zawsze równy zawsze będzie równy .
Zmiana Foo
na automatyczną właściwość z seterem private
usuwa to ostrzeżenie, ale nie chcę tego robić (nie lubię automatycznych właściwości z ustawieniami prywatnymi).
Co muszę zmienić w powyższym kodzie, aby ostrzeżenie zniknęło z zachowaniem pola _foo
?
Następujące nie działa:
- Zmiana
IsFooSet
używać_foo
zamiastFoo
. Spowoduje to dodatkowe "zapewnia niepotwierdzone" naIsFooSet
. - Dodawanie niezmiennika
Foo == _foo
. Spowoduje to "niezmienione niezmienione" na domyślnym, domyślnym konstruktorze. Co więcej, na podstawie rzeczywistych kodów czas przetwarzania statycznego kontrolera będzie wyższy o magnitudo. - Dodanie
Contract.Ensures(Contract.Result<string>() == _foo);
do pobierającego zFoo
zgodnie z this answer nic nie zmienia.
To nie pomoże w rozwiązaniu problemu, ale mogę zapytać, dlaczego nie lubisz automatyczne właściwości z ustawiaczami prywatnymi? – ken2k
W większości przypadków te właściwości są niezmiennikami klasy, tj. Pole kopii powinno być wykonane tylko do odczytu. Nie jest to możliwe w przypadku właściwości automatycznych. W rzeczywistości staram się całkowicie unikać właściwości automatycznych. Powody są opisane [tutaj] (http://blog.ploeh.dk/2011/05/26/CodeSmellAutomaticProperty.aspx). –
Czy zostałby usunięty, jeśli domyślnie ustawisz "_foo" na pusty ciąg znaków? Wygląda na to, że problem polega bardziej na tym, że domyślną wartością '_foo' będzie" null ". –