2013-05-04 13 views
7

W języku C#, chcę zrobić "inteligentne" wyliczenia, coś jak to jest możliwe w Javie, gdzie jest więcej informacji dołączonych do wartości wyliczeniowej niż tylko bazowa int. I stało się po schemat dokonywania klasę (zamiast wyliczenia), jak w poniższym prostym przykładzie:C# zmienność - Analiza kodu VS daje mi CA2104? Wydaje się ... biedny. Czy nie rozumiem?

public sealed class C 
{ 
    public static readonly C C1 = new C(0, 1); 
    public static readonly C C2 = new C(2, 3); 

    private readonly int x; 
    private readonly int y; 

    private C(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public int X 
    { 
     get 
     { 
      return this.x; 
     } 
    } 

    public int Y 
    { 
     get 
     { 
      return this.y; 
     } 
    } 
} 

Ale kiedy uruchomić Visual Studio „Code Analyzer” na tym, że daje mi ostrzeżenie C2104 " Nie zadeklaruj typów referencyjnych, które można modyfikować tylko do odczytu ".

Rozumiem, dlaczego generalnie nie chciałbyś zadeklarować typów referencyjnych tylko do odczytu, ale ... moja klasa nie jest zmienna, czyż nie?

Czytanie dokumentów dla ostrzeżenia, wydaje się, że są one po prostu rodzajem założenia, że ​​każdy typ odwołania tylko do odczytu jest zmienna. Na przykład, mówi, że jeśli typ naprawdę jest niezmienny, możesz zignorować to ostrzeżenie. A w rzeczywistości daje mi to samo ostrzeżenie o następującej jeszcze prostszy zajęć:

public sealed class C 
{ 
    public static readonly C C1 = new C(); 
    public static readonly C C2 = new C(); 

    private C() 
    { 
    } 
} 

Tak, OK, chyba że jestem poważnie nieporozumienie zmienność, CA2104 nie rozumie. I zalecenie to jest dla mnie, aby stłumić ostrzeżenie dla każdej linii, w której pojawia się, o ile jestem pewien, że klasa jest naprawdę niezmienna. Ale:

(1) Więc jeśli nie wyłączę tej kontroli całkowicie, muszę ją zignorować za każdym razem, gdy używam niezmiennego członka tylko do odczytu, co mogę zrobić setkami razy dla każdego wyliczenia?

(2) Ale gorzej, nawet jeśli to zrobię, to ktoś może później przypadkowo wprowadzić zmienność, ale ktoś jeszcze będzie miał fałszywe poczucie bezpieczeństwa, ponieważ fakt, że ktoś ręcznie stłumił to stwierdzenie "Sprawdziłem a to jest niezmienne "?

+0

Miałem podobne pytanie: http://stackoverflow.com/questions/15740025/the-ca2104-warning-is-there-any-way-to-mark-a-class-as-immutable- to-suppress –

Odpowiedz

5

Masz rację - w tym scenariuszu jest to błąd fałszywy. Jedynymi wyborami są pojedyncze pomijanie lub wyłączanie ostrzeżenia, a wady są dokładnie takie, jak opisano dla każdej opcji.

Inne opcje, aby uniknąć tego ostrzeżenia to:

  • nie wolno używać pól statycznych. Zamiast tego można użyć właściwości statycznej z publicznym zbiorem get i prywatnym i zainicjować w konstruktorze zamiast w postaci inline.

  • Wprowadź te niezmienne typy wartości, które pomijają ostrzeżenie, ale potencjalnie powodują inne zachowanie w niektórych sytuacjach. To może, ale nie musi być opcja w twoim przypadku.

+0

Zmiana na typ wartości zadziałała - dziękuję! Myślę, że powinno to być w porządku, ponieważ chcę z niego korzystać, więc zacznę to robić w ten sposób i poradzę sobie z innymi problemami, które mogą pojawić się, gdy się z nimi spotkam. Dzięki jeszcze raz! – user2350774

+0

@ user2350774 Korzystanie z właściwości to w rzeczywistości moje preferencje. Pola publiczne mają wiele wad (możesz tu szukać z mnóstwa powodów, dla których warto unikać pól w publicznym interfejsie API) –

+0

Nie jestem pewien, czy rozumiem - użyłem właściwości dla X i Y. Czy sugerujesz, że powinienem również użyć właściwości dla rzeczy statycznych, które chcę traktować, w gruncie rzeczy, jako wartości wyłudzające? – user2350774