Czy stałe publiczne są „złe”?

38

Czy to jest:

public MyClass
{
    public const string SomeString = "SomeValue";
}

gorzej niż to:

public MyClass
{
    public static string SomeString { get{ return "SomeValue";}}
}

Do obu można odwoływać się w ten sam sposób:

if (someString == MyClass.SomeString)
     ...

Drugi jednak ma ochronę bycia własnością. Ale tak naprawdę, o ile lepsze to jest od stałego?

Nauczyłem się w kółko niebezpieczeństw posiadania pól publicznych. Więc kiedy zobaczyłem trochę kodu używającego tych stałych w polach publicznych, natychmiast zabrałem się do refaktoryzacji ich do właściwości. Ale w połowie zastanawiałem się, jaką korzyścią byłoby mieć statyczne właściwości nad stałymi.

Jakieś pomysły?

Vaccano
źródło
1
Stałe publiczne używane w ten sposób są w porządku. Korzystanie z właściwości w ten sposób to przesada.
Bernard,
2
Czy rozważałeś użycie słowa kluczowego tylko do odczytu ? ReadOnly zapewnia czystszą syntanx const bez problemów wymienionych w wielu postach.
Matt Raffel
Mógłby również zrobić ... publiczny statyczny tylko do odczytu typ constantName = 0;
Snoop,

Odpowiedzi:

56

W języku C # jest bardzo źle z żadnego z powodów wymienionych w tym wątku.

Stałe publiczne w języku C # zostają upieczone w odwołaniach do zestawów. Oznacza to, że jeśli SomeOtherClass znajduje się w oddzielnym zestawie odwołującym się do SomeString w MyClass, CIL wygenerowany dla SomeOtherClass będzie zawierać zakodowany ciąg „SomeValue”.

Jeśli ponownie wdrożysz bibliotekę DLL, która zawiera MyClass, ale nie SomeOtherClass, i zmienisz const, SomeOtherClass nie będzie zawierał tego, co według ciebie będzie - będzie zawierał oryginalną wartość.

Jeśli jesteś w 100% pozytywny, to uniwersalna stała jak Pi, oszalej; w przeciwnym razie stąp ostrożnie.

Oto lepsze wyjaśnienie: https://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly

Brian
źródło
3
@Oded, ale ta sama różnica dotyczy constwłaściwości tylko do odczytu. constjest wstawiany do zestawu wywołującego, właściwość tylko do odczytu nie jest.
sick
1
Tego nie wiedziałem. Jest to kolejny dowód na to, że pola publiczne są złe. Myślę, że nawet „bezpieczny” przykład Pi jest złym pomysłem (co powiesz na to, kiedy deweloper chce mniej lub bardziej precyzyjnych cyfr na Pi? I dokonuje zmian w zestawie, nie znając tego problemu). Mam ponad 40 zespołów rozwiązanie i widziałem, że to naprawdę nas gryzie, jeśli nie będziemy ostrożni.
Vaccano
2
Czy ta „kopia” występuje w innych częściach C #? (tj.
śliwki
2
Tak, kopia się dzieje. Zwykle nie jest to problem, ale jeśli Twój kod korzysta z wartości liczbowej Enum i jest zmieniany w sposób opisany w tym pytaniu, może to powodować problemy.
Vaccano
1
Jest to jeden z głównych powodów, dla których constw C # jest głupi. Potrzebujemy lepszego wsparcia dla niezmiennych ...
KChaloux
22

Zmiana pola we właściwość jest przełomową zmianą. Tracisz zgodność binarną, źródłową i refleksyjną.

Dodatkowo:

  • Istnieje bardziej szczegółowa kontrola dostępu z właściwościami. Czy chcesz, aby był publicznie dostępny, ale tak naprawdę chcesz tylko z zabezpieczonym dostępem? Nie ma problemu (przynajmniej od C # 2).
  • Chcesz włamać się do debugera przy każdej zmianie wartości? Po prostu dodaj punkt przerwania w seterze.
  • Chcesz zalogować cały dostęp? Po prostu dodaj logowanie do gettera.
  • Właściwości są używane do wiązania danych; pola nie są.

http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx

To powiedziawszy, nie widzę, jak naprawdę wpływa to na stałe (szczególnie jeśli nie potrzebujesz żadnej z powyższych funkcji), chyba że twój interfejs API zmieni się w taki sposób, że nie będą już stałymi.

Robert Harvey
źródło
11

Zagrożenia dla pól publicznych polegają na tym, że są one zmienne, a implementacja leżąca u ich podstaw może ulec zmianie.

Jeśli chodzi o constto, zwykle nie jest to problem (podobnie jak publiczne wyliczenia) - chyba że uważasz, że constskończy się to jako zmienne i że będziesz potrzebował pewnego czasu otoczenia wokół akcesorium (powiedz, żeby zalogować, ile razy wyglądało w górę), równie dobrze możesz zachować ją jako publiczną const.

Oded
źródło
1

Stała to dane. Właściwości implikują możliwość zachowania się, gdy „spojrzysz” na wartość.

Łączenie zachowania (lub jego przyszłej możliwości) ze stałymi danymi jest całkowicie błędne. W przypadku większości systemów nie ma to większego znaczenia, ale może.

Powiedzmy, że wartość „PI” jest szeroko stosowana w obliczeniach systemu. Umieszczenie go za właściwościami zmusi programistów-klientów do programowania w obronie. Muszą przypisać wartość do zduplikowanej stałej. Jeśli nie zostaną skopiowane, w następnej wersji biblioteki może pojawić się niechciane „zachowanie” za właściwością. Zachowanie właściwości (jeśli jest w skompilowanej bibliotece) jest nieznane. Może działa dobrze w teście, ale może istnieć ukryty kod, który zostanie wykonany, jeśli zostanie spełniony specjalny warunek. To nie jest optymalizacja przedwczesna. Zwłaszcza w systemie czasu rzeczywistego zależy od życia ludzi.

Programiści klienta mogą nawet stracić bezpieczeństwo stałej, ponieważ język może nie pozwolić im przypisać wartości właściwości do ich zduplikowanej stałej.

Ponadto, gdy programiści są zmuszeni przypisać wartość twojej własności do swojej stałej, skutecznie niwelują wszelkie zachowanie, które chciałeś osiągnąć z twoją właściwością.

Prawdziwie stałe dane nie wymagają ani nie wymagają enkapsulacji.

Lord Tydus
źródło