Static readonly vs const

Czytałem o polach const i static readonly. Mamy kilka klas, które zawierają tylko stałe wartości. Używany do różnych rzeczy w naszym systemie. Więc zastanawiam się, czy moje spostrzeżenie jest poprawne:

Czy tego rodzaju stałe wartości zawsze powinny być static readonly dla wszystkiego, co jest publiczne? I używać tylko const dla wewnętrznych/chronionych/prywatnych wartości?

Co polecacie? Czy powinienem w ogóle nie używać pól static readonly, ale raczej używać właściwości?
 1219
Author: John Saunders, 2009-04-16

15 answers

public static readonly pola są nieco nietypowe; właściwości public static (tylko z get) byłyby bardziej powszechne (być może wspierane przez pole private static readonly).

const wartości są wypalane bezpośrednio w miejscu wywołania; jest to obosieczne:

  • jest bezużyteczne, jeśli wartość jest pobierana w trybie runtime, być może z config
  • jeśli zmienisz wartość const, musisz przebudować wszystkich klientów
  • ale może być szybszy, ponieważ unika wywołania metody...
  • ...które czasami mogą w każdym razie nie było to możliwe.]}

Jeśli wartość nigdy nie zmieni się , to const jest w porządku - Zero itp. robią rozsądne const ;P poza tym, static właściwości są bardziej powszechne.

 841
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 04:58:30

Użyłbym static readonly, Jeśli konsument jest w innym zespole. Posiadanie constI konsumenta w dwóch różnych zespołach jest dobrym sposobem, abystrzelić sobie w stopę .

 206
Author: Michael Stum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-25 16:50:58

Some other things

Const int a

  • musi być zainicjalizowana
  • inicjalizacja musi być w czasie kompilacji

Readonly int a

  • może używać wartości domyślnej, bez inicjalizacji
  • inicjalizacja może być w czasie wykonywania
 176
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-10 17:04:12

To tylko uzupełnienie do innych odpowiedzi. Nie będę ich powtarzał (teraz cztery lata później).

Są sytuacje, w których a const i a non-const mają różne semantyki. Na przykład:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

Wypisuje True, natomiast:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

Pisze False.

Powodem jest to, że metoda x.Equals ma dwa przeciążenia, jeden, który bierze w short (System.Int16) i taki, który bierze object (System.Object). Teraz pytanie brzmi, czy jeden lub oba stosuje się z moim y kłótnia.

Gdy y jest stałą czasu kompilacji (literalną), przypadek const, ważne staje się, że istnieje konwersja implicit Z int na short pod warunkiem, że int jest stałą i pod warunkiem, że kompilator C# weryfikuje, czy jego wartość mieści się w zakresie short (który 42 jest). Zobacz Implicit constant expression conversions w specyfikacji języka C#. Więc oba przeciążenia muszą być brane pod uwagę. Przeciążenie Equals(short) jest preferowane (dowolne short jest object, ale nie wszystkie objectshort). Tak więc y jest konwertowane na short, a to przeciążenie jest używane. Następnie Equals porównuje dwa short o identycznej wartości, co daje true.

Gdy y nie jest stałą, nie istniejeniejawna konwersja z int do short. To dlatego, że ogólnie int może być zbyt duży, aby zmieścić się w short. (An explicit konwersja istnieje, ale nie powiedziałem Equals((short)y), więc to nie ma znaczenia.) Widzimy, że stosuje się tylko jedno przeciążenie, Equals(object) jedno. Więc {[10] } jest spakowane do object. Następnie Equals porównuje System.Int16 do System.Int32, a ponieważ typy run-time nawet się nie zgadzają, to daje false.

Wnioskujemy, że w niektórych (rzadkich) przypadkach zmiana elementu typu const na pole typu static readonly (lub w inny sposób, gdy jest to możliwe) może zmienić zachowanie programu.

 157
Author: Jeppe Stig Nielsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-13 13:30:01

Należy zauważyć, że const jest ograniczony do typów prymitywnych / wartości (wyjątkiem są łańcuchy)

 83
Author: Chris S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-16 11:28:51

Słowo kluczowe readonly różni się od słowa kluczowego const. Pole const może być inicjowane tylko w deklaracji pola. Pole readonly może być zainicjalizowane w deklaracji lub w konstruktorze. Dlatego pola readonly mogą mieć różne wartości w zależności od użytego konstruktora. Ponadto, podczas gdy pole const jest stałą czasu kompilacji, pole readonly może być używane dla stałych runtime

Krótkie i przejrzyste odniesienie do MSDN tutaj

 23
Author: yazanpro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-14 18:58:37

Tylko Do Odczytu Statycznego : Wartość można zmienić za pomocą konstruktora static w czasie wykonywania. Ale nie poprzez funkcję członka.

Stała : Domyślnie static. Wartość nie może być zmieniana z dowolnego miejsca(ctor, Function, runtime itd no-where).

Tylko Do Odczytu : Wartość może być zmieniana przez konstruktor w czasie wykonywania. Ale nie poprzez funkcję członka.

Możesz rzucić okiem na moje repo: C # Typy właściwości.

 17
Author: Yeasin Abedin Siam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 04:59:23

const i readonly są podobne, ale nie są dokładnie takie same.

A const jest stałą czasu kompilacji, co oznacza, że wartość ta może być obliczona w czasie kompilacji. Pole readonly umożliwia dodatkowe scenariusze, w których część kodu musi być uruchomiona podczas budowy typu. Po zbudowaniu pole readonly nie może zostać zmienione.

Na przykład, const Członkowie mogą być używane do definiowania członków takich jak:

struct Test
{
    public const double Pi = 3.14;
    public const int Zero = 0;
}

Ponieważ wartości takie jak 3.14 i 0 są stałymi czasu kompilacji. Rozważ jednak przypadek, w którym zdefiniujesz typ i chcesz podać kilka jego początkowych wystąpień. Na przykład możesz zdefiniować klasę kolorów i podać "stałe" dla popularnych kolorów, takich jak czarny, biały itp. Nie można tego zrobić z elementami const, ponieważ prawa strona nie jest stała czasu kompilacji. Można to zrobić ze zwykłymi statycznymi członkami:

public class Color
{
    public static Color Black = new Color(0, 0, 0);
    public static Color White = new Color(255, 255, 255);
    public static Color Red   = new Color(255, 0, 0);
    public static Color Green = new Color(0, 255, 0);
    public static Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

Ale wtedy nie ma nic, co powstrzyma klienta koloru od mucking z nim, być może poprzez zamianę Czarno-biały wartości. Nie trzeba dodawać, że spowodowałoby to konsternację dla innych klientów klasy kolorów. Funkcja "readonly" odnosi się do tego scenariusza.

Po prostu wprowadzając słowo kluczowe readonly w deklaracjach, zachowujemy elastyczną inicjalizację, jednocześnie zapobiegając blokowaniu kodu klienta.

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red   = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

Warto zauważyć, że członkowie const są zawsze statyczne, podczas gdy członkowie readonly mogą być statyczne lub nie, tak jak zwykłe pole.

Jest możliwe jest użycie jednego słowa kluczowego do tych dwóch celów, ale prowadzi to do problemów z wersjonowaniem lub problemów z wydajnością. Załóżmy przez chwilę, że użyliśmy jednego słowa kluczowego dla tego (const) i programista napisał:

public class A
{
    public static const C = 0;
}

I inny programista napisał kod, który opierał się na:

public class B
{
    static void Main() => Console.WriteLine(A.C);
}

Czy wygenerowany kod może polegać na tym, że A. C jest stałą czasu kompilacji? Czyli czy użycie A. C można po prostu zastąpić wartością 0? Jeśli powiesz " Tak " temu, wtedy to oznacza to, że deweloper A nie może zmienić sposobu inicjowania A. C.-wiąże To ręce dewelopera a bez pozwolenia.

Jeśli powiesz " nie " na to pytanie, pominięcie ważnej optymalizacji. Być może autor A jest pozytywny, że A. C zawsze będzie zerem. Użycie const i readonly pozwala twórcy a określić intencję. Zapewnia to lepsze zachowanie wersjonowania, a także lepszą wydajność.

 13
Author: Ramesh Rajendran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 05:01:48

Preferuję używać const Kiedy tylko mogę, co jak wspomniano powyżej ogranicza się do dosłownych wyrażeń lub czegoś, co nie wymaga oceny.

Jeśli rozgrzeję się wobec tego ograniczenia, to wycofam się do statycznego readonly , z jednym zastrzeżeniem. Generalnie używałbym public static property Z getterem i zapleczem private static readonly , Jak wspomina Marc tutaj .

 11
Author: Peter Meyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:26

Statyczne pole readonly jest korzystne przy wystawianiu na inne złożenia wartość, która może ulec zmianie w późniejszej wersji.

Na przykład, załóżmy, że zbiór X wyświetla stałą w następujący sposób:

public const decimal ProgramVersion = 2.3;

Jeśli assembly Y odwołuje się do X i używa tej stałej, wartość 2.3 zostanie upieczony do assembly Y podczas kompilacji. Oznacza to, że Jeśli X zostanie później skompilowana ze stałą ustawioną na 2.4, Y będzie nadal używaj starej wartości 2.3 do czasu rekompilacji Y. A static pole readonly pozwala uniknąć tego problemu.

Innym sposobem patrzenia na to jest to, że każda wartość, która może zmiana w przyszłości nie jest z definicji stała, więc powinna nie być reprezentowany jako jeden.

 6
Author: Yagnesh Cangi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 13:44:22

Const: Const jest niczym innym jak" stałą", zmienną, której wartość jest stała, ale w czasie kompilacji. I obowiązkowe jest przypisanie mu wartości. Domyślnie const jest statyczny i nie możemy zmienić wartości zmiennej const w całym programie.

Static ReadOnly: wartość zmiennej typu static Readonly może być przypisana w czasie wykonywania lub przypisana w czasie kompilacji i zmieniona w czasie wykonywania. Ale wartość tej zmiennej można zmienić tylko w konstruktor statyczny. I nie można go dalej zmieniać. Może zmienić się tylko raz w czasie wykonywania

Reference: c-sharpcorner

 6
Author: mayank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-24 11:30:26

Const:

  1. wartość powinna być podana przy deklaracji
  2. skompiluj stałą czasową

Readonly:

  1. wartość może być podana podczas deklaracji lub podczas wykonywania przy użyciu konstruktorów.Wartość może się różnić w zależności od użytego konstruktora.
  2. stała czasu pracy
 3
Author: dasumohan89,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-11 11:28:25

Istnieje niewielka różnica między polami const i static readonly w C#.Net

Const musi być zainicjalizowany wartością w czasie kompilacji.

Const jest domyślnie statyczny i musi zostać zainicjowany stałą wartością, której nie można później modyfikować. Nie można go używać ze wszystkimi typami danych. Dla ex-DateTime. Nie może być używany z DateTime datatype.

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public static readonly string Name = string.Empty; //No error, legal

Readonly może być zadeklarowane jako statyczne, ale nie jest to konieczne. Nie ma potrzeby inicjalizacji w momencie deklaracji. Jego wartość może być przypisana lub zmieniona za pomocą konstruktora raz. Istnieje więc możliwość jednorazowej zmiany wartości pola readonly (nie ma znaczenia, czy jest statyczne czy nie), co nie jest możliwe przy const.

 2
Author: Chirag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 13:06:45

Stałe są jak sama nazwa wskazuje, polami, które się nie zmieniają i są zwykle definiowane statycznie w czasie kompilacji w kodzie.

Zmienne tylko do odczytu są polami, które mogą się zmieniać w określonych warunkach.

Mogą być inicjalizowane, gdy po raz pierwszy zadeklarujesz je jako stałą, ale zazwyczaj są inicjowane podczas budowy obiektu wewnątrz konstruktora.

Nie można ich zmienić po zainicjowaniu, w warunkach wymienionych powyżej.

Statyczne tylko do odczytu brzmi jak kiepski wybór dla mnie, ponieważ jeśli jest statyczne i nigdy się nie zmienia, więc po prostu użyj go public const, jeśli może się zmienić, to nie jest stała i wtedy, w zależności od potrzeb, możesz użyć tylko do odczytu lub tylko zwykłej zmiennej.

Kolejną ważną różnicą jest to, że stała należy do klasy, podczas gdy zmienna tylko do odczytu należy do instancji!

 1
Author: Claudiu Cojocaru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-21 22:49:32

Const : wartości zmiennej const muszą być zdefiniowane wraz z deklaracją, a następnie nie zmieni się.const są domyślnie statyczne, więc bez tworzenia instancji klasy możemy uzyskać do nich dostęp. to ma wartość w czasie kompilacji

ReadOnly: wartości zmiennej readonly możemy definiować zarówno podczas deklarowania, jak i przy użyciu konstruktora w czasie wykonywania. zmienne readonly nie mogą uzyskać dostępu bez instancji klasy.

Static readonly: static readonly wartości zmiennych możemy definiować zarówno podczas deklarowania, jak i tylko przez statyczny konstruktor, ale nie z żadnym innym konstruktorem.do tych zmiennych możemy również uzyskać dostęp bez tworzenia instancji klasy (jako zmienne statyczne).

Odczyt statyczny będzie lepszym wyborem, jeśli będziemy musieli używać zmiennych w różnych składach.Sprawdź pełne szczegóły w poniższym linku

Https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/{[18]

 0
Author: user1756922,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-27 15:57:48