2013-08-01 17 views
5

Niedawno zainstalowałem narzędzia Code Contracts Tools (Code Contracts dla .NET) i Code Contracts Editor Extensions VS2012, i mam problem z uruchomieniem statycznego kontrolera prawidłowo.Code Contracts sprawdzanie statyczne pozornie nieświadome umowy. Zalety ReadOnlyCollection <T> konstruktor

Kiedy biegnę statycznego sprawdzania kontrakty kod na poniższym kodzie (z drugim założeniu zakomentowanym)

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics.Contracts; 

public class TestClass 
{ 
    public ReadOnlyCollection<byte> Foo() 
    { 
     Contract.Ensures(Contract.Result<ReadOnlyCollection<byte>>().Count == 4); 

     IList<byte> list = new byte[4]; 
     Contract.Assume(list.Count == 4); 
     var returnValue = new ReadOnlyCollection<byte>(list); 
     //Contract.Assume(returnValue.Count == 4); 
     return returnValue; 
    } 
} 

otrzymuję «zapewnia niesprawdzone» Ostrzeżenie przeczytać:

CodeContracts: zapewnia niesprawdzone: Contract.Result<ReadOnlyCollection<byte>>().Count == 4

Twierdzi, że zapewnienie metody Foo nie zostało udowodnione. Jednak, kiedy myszy nad constructor z ReadOnlyCollection<T>, mogę powiedzieć, że własność wybudowanego obiektu Count jest zapewniona będzie równa właściwość parametru listCount: Constructor mouseover

Oznacza to, że kontroler statyczny powinien być w stanie stwierdzić, że returnValue.Count == 4 (tj. gwarancje Foo) są prawdziwe. Jeśli odkomentuję drugie założenie, ostrzeżenie zniknie, ale zakładając, że zapewnione przeze mnie metody są prawdziwe, bardzo mocno koliduje z celem statycznego kontrolera.

Myślę, że problemem może być to, że tylko przedłużenie edytor jest świadomy montażu referencyjnej zawierającej kontrakt, zapewnia dla konstruktora (mscorlib.Contracts.dll), więc to, że kontrakty wymienia sprawdzania statyczny jest nieświadomy.

Próbowałem już majstrować przy ustawieniu ścieżek bibliotek dodatkowych dla całego projektu i nie sądzę, że jest to właściwy sposób rozwiązania problemu.

Czy mam rację, twierdząc, że układ kontrolny statyczny nie jest prawidłowo skonfigurowany w zestawie referencyjnym do umowy lub czy brakuje mi czegoś innego? Jeśli mam rację, jak mam naprawić konfigurację?

Używam

  • Ostateczny Visual Studio 2012 Update 3
  • Code Contracts wersję Narzędzia 1.5.60502.11
  • Code Contracts Edytor Rozszerzenia VS2012 1.5.64024.12

Edycja: Sprawdzanie statyczne wydaje się znaleźć zespoły referencyjne umowy, i działa tak, jak się spodziewałem po raz pierwszy byłoby z innymi klasami, a nawet metodami klasy ReadOnlyCollection<T>. Analiza statyczna, na przykład, poniższej metody działa dobrze.

public int Boo() 
    { 
     Contract.Ensures(-1 <= Contract.Result<int>()); 
     Contract.Ensures(Contract.Result<int>() < 4); 

     IList<byte> list = new byte[4]; 
     var collection = new ReadOnlyCollection<byte>(list); 
     Contract.Assume(collection.Count == 4); 
     return collection.IndexOf(0); 
    } 

Założenie o nieruchomości Count jest wymagane, ponieważ, zapewnia konstruktora nadal nie działa. Z drugiej strony zabezpieczenia metody IndexOf działają bardzo dobrze.

Teraz zastanawiam się tylko, dlaczego statyczny kontroler nie rozpoznaje zapewnień konstruktora ReadOnlyCollection<T>. Czy to może być błąd w analizatorze statycznym?

Odpowiedz

0

Umowy na kod mogą podnosić to ostrzeżenie, ponieważ właściwość Liczba w klasie ReadOnlyCollection nie jest stała.

W poniższym przykładzie tworzę instancję klasy ReadOnlyCollection, przekazując listę zawierającą 4 liczby całkowite. Właściwość Count zwraca wartość 4. Później modyfikuję listę zapakowaną przez ReadOnlyCollection, usuwając ją i dodając 3 liczby całkowite. Właściwość Count liczby ReadOnlyCollection teraz zwraca wartość 3 bez mnie dotknął ReadOnlyCollection.

IList<byte> list = new List<byte>() { 1, 2, 3, 4 }; 
var collection = new ReadOnlyCollection<byte>(list); 

// Outputs: 1, 2, 3, 4. 
foreach (var item in collection) 
{ 
    Console.WriteLine(item); 
} 

list.Clear(); 
list.Add(5); 
list.Add(6); 
list.Add(7); 

// Outputs: 5, 6, 7 
Console.WriteLine(); 
foreach (var item in collection) 
{ 
    Console.WriteLine(item); 
} 

Console.ReadKey(); 
Powiązane problemy