Jaka jest różnica między const a readonly w C #?

1361

Jaka jest różnica między consti readonlyw C #?

Kiedy używałbyś jednego nad drugim?

Tylko czytać
źródło
Musiałem spojrzeć w dół na kilka odpowiedzi, aby znaleźć ten link, ale jest dobry. Eric Lippert przyjmuje niezmienność w C #
Frank Bryce,
2
@donstack, faktycznie zgodnie z odniesieniem do C # , pole tylko do odczytu można przypisać i przypisać wiele razy w deklaracji pola i konstruktorze.
Marques

Odpowiedzi:

1289

Oprócz widocznej różnicy

  • konieczność zadeklarowania wartości w czasie definicji wartości constVS readonlymoże być obliczana dynamicznie, ale musi zostać przypisana przed wyjściem konstruktora. Po tym jest zamrożona.
  • 'const' są niejawnie static. ClassName.ConstantNameAby uzyskać do nich dostęp, użyj notacji.

Jest subtelna różnica. Rozważ klasę zdefiniowaną w AssemblyA.

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly int I_RO_VALUE;
  public Const_V_Readonly()
  {
     I_RO_VALUE = 3;
  }
}

AssemblyBodwołuje się AssemblyAi używa tych wartości w kodzie. Po skompilowaniu

  • w przypadku constwartości jest to jak szukanie-zamiana, wartość 2 jest „wypalona” w AssemblyBIL. Oznacza to, że jeśli jutro zaktualizuję I_CONST_VALUEdo 20 w przyszłości. AssemblyBmiałbym jeszcze 2, dopóki go nie skompiluję .
  • w przypadku readonlywartości jest jak refw pamięci. Wartość nie jest wprowadzana do AssemblyBIL. Oznacza to, że jeśli lokalizacja pamięci zostanie zaktualizowana, AssemblyBotrzymuje nową wartość bez ponownej kompilacji. Jeśli więc I_RO_VALUEzaktualizowano do 30, wystarczy tylko zbudować AssemblyA. Nie trzeba ponownie kompilować wszystkich klientów.

Więc jeśli masz pewność, że wartość stałej się nie zmieni, użyj a const.

public const int CM_IN_A_METER = 100;

Ale jeśli masz stałą, która może się zmienić (np. Precyzja zapisu) .. lub w razie wątpliwości użyj readonly.

public readonly float PI = 3.14;

Aktualizacja: Aku musi uzyskać wzmiankę, ponieważ najpierw zwrócił na to uwagę. Muszę też podłączyć tam, gdzie się tego nauczyłem ... Skuteczne C # - Bill Wagner

Gishu
źródło
77
staticPunktem wydaje się być najważniejszym i użyteczny punkt -consts are implicitly static
LCJ
28
Najważniejsza jest część dotycząca wartości odniesienia. Stałe wartości można zoptymalizować.
CodingBarfield
22
readonlyzmienne można zmieniać poza konstruktorem (odbicie). Tylko kompilator próbuje ci przeszkodzić w modyfikowaniu var poza konstruktorem.
Bitterblue
12
readonlyZmienne @ mini-me nie mogą być zmieniane po zakończeniu działania konstruktora, nawet poprzez odbicie. Środowisko wykonawcze nie wymusza tego. Środowisko wykonawcze nie zdarza się również do egzekwowania, które nie zmieniają string.Emptysię "Hello, world!", ale nadal nie będzie twierdzić, że to sprawia, string.Emptymodyfikować lub że kod nie należy zakładać, że string.Emptyzawsze będzie ciągiem o zerowej długości.
7
blogs.msmvps.com/jonskeet/2014/07/16/… to interesujący, tylko do odczytu, ogólny koszt tylko do odczytu
CAD CAD
275

Jest gotcha z stałymi! Jeśli odwołujesz się do stałej z innego zestawu, jej wartość zostanie skompilowana bezpośrednio w zestawie wywołującym. W ten sposób, gdy zaktualizujesz stałą w referencyjnym zestawie, nie zmieni się ona w zestawie wywołującym!

aku
źródło
8
Podczas dekompilacji (Reflector, ILSpy, ...) do stałej NIGDY NIE DOTYCZY żaden, niezależnie od tego samego zestawu lub innego zestawu, więc nie można w ogóle analizować użycia stałej w skompilowanym kodzie.
springy76
159

Stałe

  • Stałe są domyślnie statyczne
  • Muszą mieć wartość w czasie kompilacji (możesz mieć np. 3.14 * 2, ale nie możesz wywoływać metod)
  • Może być zadeklarowany w ramach funkcji
  • Są kopiowane do każdego zestawu, który ich używa (każdy zestaw otrzymuje lokalną kopię wartości)
  • Może być stosowany w atrybutach

Pola instancji tylko do odczytu

  • Musi mieć ustawioną wartość, zanim konstruktor zakończy pracę
  • Są oceniane podczas tworzenia instancji

Statyczne pola tylko do odczytu

  • Są oceniane, gdy wykonanie kodu trafia na odwołanie do klasy (gdy tworzona jest nowa instancja lub wykonywana jest metoda statyczna)
  • Musi mieć oszacowaną wartość do czasu ukończenia konstruktora statycznego
  • Nie zaleca się umieszczania na nich ThreadStaticAttribute (konstruktory statyczne będą wykonywane tylko w jednym wątku i ustawią wartość dla tego wątku; wszystkie inne wątki będą miały tę wartość niezainicjowaną)
splattne
źródło
58

Aby dodać, ReadOnly tylko dla typów referencji powoduje, że referencja jest tylko do odczytu, a nie wartości. Na przykład:

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};

  public UpdateReadonly()
  {
     I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
     I_RO_VALUE = new char[]{'V'}; //will cause compiler error
  }
}

źródło
Czy istnieje jakikolwiek inny typ odniesienia string, którego można użyć jako stałej?
springy76
Możesz mieć constz typami referencyjnymi innymi niż string, ale stała może mieć tylko wartość null.
Mike Rosoft
40

To wyjaśnia to . Podsumowanie: const musi być zainicjowany w czasie deklaracji, tylko do odczytu może zostać zainicjowany na konstruktorze (a zatem ma inną wartość w zależności od użytego konstruktora).

EDYCJA: Zobacz wyżej Gchau dla subtelnej różnicy

Vinko Vrsalovic
źródło
32

const: Nigdzie nie można tego zmienić.

readonly: Tę wartość można zmienić tylko w konstruktorze. Nie można go zmienić w normalnych funkcjach.

Deepthi
źródło
26

Jest mała gotcha z tylko do odczytu. Pole tylko do odczytu można ustawić wiele razy w konstruktorze (konstruktorach). Nawet jeśli wartość jest ustawiona w dwóch różnych konstruktorach łańcuchowych, jest nadal dozwolona.


public class Sample {
    private readonly string ro;

    public Sample() {
        ro = "set";
    }

    public Sample(string value) : this() {
        ro = value; // this works even though it was set in the no-arg ctor
    }
}
Mike Two
źródło
26

Element stały jest definiowany w czasie kompilacji i nie można go zmienić w czasie wykonywania. Stałe są deklarowane jako pole za pomocą constsłowa kluczowego i muszą być inicjowane w trakcie deklaracji.

public class MyClass
{
    public const double PI1 = 3.14159;
}

Członek readonlyjest jak stała, ponieważ reprezentuje niezmienną wartość. Różnica polega na tym, że element readonlyczłonkowski można zainicjować w środowisku wykonawczym, w konstruktorze, a także można go zainicjować w miarę ich deklarowania.

public class MyClass1
{
     public readonly double PI2 = 3.14159;

     //or

     public readonly double PI3;

     public MyClass2()
     {
         PI3 = 3.14159;
     }
}

const

  • Nie można ich zadeklarować jako static (są domyślnie statyczne)
  • Wartość stałej jest oceniana w czasie kompilacji
  • stałe są inicjowane tylko w deklaracji

tylko czytać

  • Mogą być na poziomie instancji lub statyczne
  • Wartość jest oceniana w czasie wykonywania
  • tylko do odczytu można zainicjować w deklaracji lub za pomocą kodu w konstruktorze
Sujit
źródło
6
Nie mogą być statyczne , są statyczne. Powinieneś to wyjaśnić, jeśli miałeś na myśli, że nie można zadeklarowaćstatic const int i = 0;
nawfal
Czy możesz wyjaśnić, dlaczego constdeklaracje nie mogą być składane wewnątrz metod?
Minh Tran
21

Stała jest stałą czasu kompilacji, natomiast tylko do odczytu pozwala na obliczenie wartości w czasie wykonywania i ustawienie w konstruktorze lub inicjalizatorze pola. Zatem „stała” jest zawsze stała, ale „tylko do odczytu” jest przypisana tylko do odczytu.

Eric Lippert z zespołu C # ma więcej informacji na temat różnych rodzajów niezmienności

Jazda na jednym kole
źródło
15

Oto kolejny link pokazujący, w jaki sposób const nie jest bezpieczny w wersji lub odpowiedni dla typów referencji.

Podsumowanie :

  • Wartość właściwości const jest ustawiana w czasie kompilacji i nie może się zmieniać w czasie wykonywania
  • Stała nie można oznaczyć jako statyczną - słowo kluczowe oznacza, że ​​są statyczne, w przeciwieństwie do pól tylko do odczytu, które mogą.
  • Stała nie może być niczym innym niż typem wartości (prymitywnym)
  • Słowo kluczowe tylko do odczytu oznacza pole jako niezmienne. Jednak właściwość można zmienić wewnątrz konstruktora klasy
  • Słowo kluczowe tylko do odczytu można również połączyć ze statycznym, aby działało w ten sam sposób co const (przynajmniej na powierzchni). Istnieje znacząca różnica, gdy spojrzysz na IL między nimi
  • stałe pola są oznaczone jako „dosłowne” w IL, podczas gdy tylko do odczytu jest „początkowo”
Chris S.
źródło
11

Tylko do odczytu : Wartość można zmienić za pomocą Ctor w czasie wykonywania. Ale nie poprzez funkcję członka

Stała : Defult static. Wartości nie można zmienić z dowolnego miejsca (Ctor, funkcja, środowisko uruchomieniowe itp. Nigdzie)

Yeasin Abedin Siam
źródło
dziękuję, że nie kazałeś mi czytać 4 akapitów tylko za te dwa dania na wynos ...
Don Cheadle
6

Uważam, że constwartość jest taka sama dla wszystkich obiektów (i musi być inicjowana dosłownym wyrażeniem), podczas gdy readonlymoże być inna dla każdej instancji ...

Daren Thomas
źródło
5

Jeden z członków zespołu w naszym biurze udzielił następujących wskazówek, kiedy stosować const, static i readonly:

  • Używaj const, gdy masz zmienną typu, który możesz znać w czasie wykonywania (literał łańcuchowy, int, double, enum, ...), że chcesz, aby wszystkie wystąpienia lub konsumenci klasy mieli dostęp do miejsca, w którym wartość nie powinna się zmieniać.
  • Użyj statycznego, gdy masz dane, które mają umożliwić wszystkim instancjom lub konsumentom klasy dostęp do miejsca, w którym wartość może się zmienić.
  • Użyj statycznego tylko do odczytu, gdy masz zmienną typu, której nie możesz znać w czasie wykonywania (obiekty), i chcesz, aby wszystkie instancje lub konsumenci klasy mieli dostęp do miejsca, w którym wartość nie powinna się zmienić.
  • Używaj tylko do odczytu, gdy masz zmienną na poziomie instancji, którą znasz podczas tworzenia obiektu, która nie powinna się zmienić.

Ostatnia uwaga: stałe pole jest statyczne, ale odwrotność nie jest prawdziwa.

Scott Lawrence
źródło
1
Myślę, że masz na myśli „rozmawiać”. Odwrotnością byłoby „pole niestałe nie jest statyczne”. Co może, ale nie musi być prawdą. Przeciwnie, „pole statyczne jest (zawsze) stałe” nie jest prawdziwe.
Michael Blackburn
5

Oba są stałe, ale stała jest dostępna również w czasie kompilacji. Oznacza to, że jednym aspektem różnicy jest to, że można używać zmiennych const jako danych wejściowych do konstruktorów atrybutów, ale nie zmiennych tylko do odczytu.

Przykład:

public static class Text {
  public const string ConstDescription = "This can be used.";
  public readonly static string ReadonlyDescription = "Cannot be used.";
}

public class Foo 
{
  [Description(Text.ConstDescription)]
  public int BarThatBuilds {
    { get; set; }
  }

  [Description(Text.ReadOnlyDescription)]
  public int BarThatDoesNotBuild {
    { get; set; }
  }
}
Hallgrim
źródło
5
  • kiedy stosować constlubreadonly

    • const

      • stała czasowa kompilacji: stała bezwzględna , wartość jest ustalana podczas deklaracji, jest w samym kodzie IL
    • readonly

      • run-time stały: można ustawić w konstruktorze Init poprzez pliku config / ie App.config, ale gdy inicjuje on nie może być zmieniona
Ryan Efendy
źródło
4

Zmienne oznaczone jako const są niewiele więcej niż silnie wpisanymi makrami #define, w czasie kompilacji odniesienia do zmiennych const są zastępowane wbudowanymi wartościami literałowymi. W konsekwencji można w ten sposób wykorzystywać tylko niektóre wbudowane pierwotne typy wartości. Zmienne oznaczone jako tylko do odczytu można ustawić w konstruktorze w czasie wykonywania, a ich tylko do odczytu jest wymuszane również w czasie wykonywania. Jest to związane z niewielkimi kosztami wydajności, ale oznacza to, że można używać tylko do odczytu dowolnego typu (nawet typów referencyjnych).

Również stałe zmienne są z natury statyczne, podczas gdy zmienne tylko do odczytu mogą być specyficzne dla instancji, jeśli jest to pożądane.

Klin
źródło
Dodano, że consts są silnie wpisane #define makra. W przeciwnym razie możemy odstraszyć wszystkich ludzi C lub C ++. :-)
Jason Baker,
4

CONST

  1. Słowo kluczowe const można zastosować do pól lub zmiennych lokalnych
  2. Musimy przypisać stałe pole w momencie deklaracji
  3. Brak przydzielonej pamięci Ponieważ wartość const jest osadzona w samym kodzie IL po kompilacji. To jest jak znaleźć wszystkie wystąpienia stałej zmiennej i zastąpić jej wartością. Zatem kod IL po kompilacji będzie miał zakodowane wartości zamiast zmiennych const
  4. Stałe w C # są domyślnie statyczne.
  5. Wartość jest stała dla wszystkich obiektów
  6. Występuje problem z wersją biblioteki dll - oznacza to, że za każdym razem, gdy zmieniamy publiczną zmienną const lub właściwość (W rzeczywistości nie powinno się jej zmieniać teoretycznie), każdy inny dll lub zestaw, który używa tej zmiennej, musi zostać przebudowany
  7. Tylko typy wbudowane w C # można zadeklarować jako stałe
  8. Pole Const nie może być przekazane jako parametr ref lub out

Tylko czytać

  1. Słowo kluczowe readonly dotyczy tylko pól, a nie zmiennych lokalnych
  2. Możemy przypisać pole tylko do odczytu w momencie deklaracji lub w konstruktorze, a nie w innych metodach.
  3. pamięć dynamiczna przydzielona do pól tylko do odczytu i możemy uzyskać wartość w czasie wykonywania.
  4. Readonly należy do obiektu utworzonego w ten sposób, do którego dostęp jest możliwy tylko poprzez instancję klasy. Aby uczynić go członkiem klasy, musimy dodać statyczne słowo kluczowe przed tylko do odczytu.
  5. Wartość może być różna w zależności od zastosowanego konstruktora (ponieważ należy do obiektu klasy)
  6. Jeśli zadeklarujesz typy inne niż pierwotne (typ odwołania) jako tylko do odczytu, tylko odwołanie jest niezmienne, a nie obiekt, który zawiera.
  7. Ponieważ wartość jest uzyskiwana w czasie wykonywania, nie ma problemu z wersją biblioteki DLL dla pól / właściwości tylko do odczytu.
  8. Możemy przekazać pole tylko do odczytu jako parametry ref lub out w kontekście konstruktora.
Muhammad VP
źródło
3

Kolejna gotcha .

Ponieważ const naprawdę działa tylko z podstawowymi typami danych, jeśli chcesz pracować z klasą, możesz czuć się „zmuszony” do korzystania z ReadOnly. Uważaj jednak na pułapkę! ReadOnly oznacza, że ​​nie można zastąpić obiektu innym obiektem (nie można sprawić, aby odnosiło się do innego obiektu). Ale każdy proces, który ma odniesienie do obiektu, może dowolnie modyfikować wartości wewnątrz obiektu!

Nie daj się zatem pomylić, że ReadOnly sugeruje, że użytkownik nie może nic zmienić. W języku C # nie ma prostej składni, aby zapobiec zmianie instancji klasy przez jej wewnętrzne wartości (o ile mi wiadomo).

Mark T
źródło
Tak, to bardziej ogólny temat. Jeśli masz właściwość get only ujawniającą listę arraylist, nadal możesz ją modyfikować. Nie można ustawić innej listy arraylist dla tej właściwości, ale nie można powstrzymać użytkownika przed zmianą listy arraylist.
Gishu,
3

A constmusi być zakodowane na stałe , gdzie readonlymożna ustawić w konstruktorze klasy.

Greg
źródło
3

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

const jest domyślnie statyczny i musi być inicjalizowany ze stałą wartością, której nie można później modyfikować. Zmiana wartości również nie jest dozwolona w konstruktorach. Nie można go używać ze wszystkimi typami danych. Dla ex-DateTime. Nie można go używać z typem danych DateTime.

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

tylko do odczytu można zadeklarować jako statyczne, ale nie konieczne. Nie ma potrzeby inicjowania w momencie deklaracji. Jego wartość można przypisać lub zmienić za pomocą konstruktora. Daje to przewagę, gdy jest używany jako element klasy instancji. Dwie różne instancje mogą mieć różną wartość pola tylko do odczytu. Na przykład -

class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}

Następnie pole tylko do odczytu można zainicjować za pomocą natychmiastowych wartości określonych w następujący sposób:

A objOne = new A(5);
A objTwo = new A(10);

Tutaj instancja objOne będzie miała wartość pola tylko do odczytu jako 5, a objTwo ma 10. To nie jest możliwe przy użyciu const.

Chirag
źródło
2

Stała zostanie skompilowana do konsumenta jako wartość dosłowna, podczas gdy ciąg statyczny będzie służył jako odniesienie do zdefiniowanej wartości.

W ramach ćwiczenia spróbuj utworzyć bibliotekę zewnętrzną i zużyć ją w aplikacji konsolowej, a następnie zmienić wartości w bibliotece i ponownie skompilować (bez ponownej kompilacji programu konsumenckiego), upuścić bibliotekę DLL do katalogu i uruchomić plik EXE ręcznie, powinieneś znaleźć że ciąg stały się nie zmienia.

Brett Ryan
źródło
Szczerze wątpię, że to prawda ... pójdę sprawdzić.
ljs
jest to jeden z 50 konkretnych sposobów na poprawę twojego C # - amazon.co.uk/Effective-Specific-Ways-Improve-Your/dp/0321245660/…
Russ Cam
@Andrew Hare - tak, właśnie sprawdziłem. Jestem bardzo zaskoczony, to jest prawdziwa gotcha, jestem naprawdę bardzo zaskoczony, zdumiony, że tak jest ...!
ljs
Sprzeciwiam się jednak stosowaniu tutaj wskaźnika słowa. Nie jest to wskazówka, że to odniesienie, a tam jest różnica w C #, jak można manipulować niezarządzanymi wskaźniki w trybie niebezpiecznym, dlatego ważne jest, aby odróżnić dwa.
ljs
2

Stały

Musimy podać wartość do pola const, gdy jest zdefiniowane. Następnie kompilator zapisuje wartość stałej w metadanych zestawu. Oznacza to, że stałą można zdefiniować tylko dla typu pierwotnego, takiego jak boolean, char, bajt i tak dalej. Stałe są zawsze uważane za elementy statyczne, a nie elementy instancji.

Tylko czytać

Pola tylko do odczytu można rozwiązać tylko w czasie wykonywania. Oznacza to, że możemy zdefiniować wartość dla wartości za pomocą konstruktora dla typu, w którym pole jest zadeklarowane. Weryfikacja jest wykonywana przez kompilator, do którego pola tylko do odczytu nie są zapisywane żadną metodą inną niż konstruktor.

Więcej informacji na temat obu wyjaśniono tutaj w tym artykule

Vikram
źródło
1

Głównie; możesz przypisać wartość do statycznego pola tylko do odczytu do wartości nie stałej w czasie wykonywania, podczas gdy stałej należy przypisać wartość stałą.

ljs
źródło
1

Const i readonly są podobne, ale nie są dokładnie takie same. Pole const jest stałą czasu kompilacji, co oznacza, że ​​tę wartość można obliczyć w czasie kompilacji. Pole tylko do odczytu umożliwia dodatkowe scenariusze, w których część kodu musi zostać uruchomiona podczas budowy tego typu. Po zakończeniu budowy pola tylko do odczytu nie można zmienić.

Na przykład stałych członków można użyć do zdefiniowania 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 czasów kompilacji. Rozważ jednak przypadek, w którym definiujesz typ i chcesz podać niektóre jego wcześniejsze wersje. Na przykład, możesz chcieć zdefiniować klasę Kolor i podać „stałe” dla typowych kolorów, takich jak Czarny, Biały itp. Nie można tego zrobić z elementami stałymi, ponieważ prawa strona nie jest stała czasu kompilacji. Można to zrobić za pomocą zwykłych elementów statycznych:

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 = r;
        green = g;
        blue = b;
    }
}

ale nie ma nic, co powstrzymałoby klienta Color od zepsucia się nim, być może poprzez zamianę wartości czerni i bieli. Nie trzeba dodawać, że spowodowałoby to konsternację u innych klientów klasy Color. Funkcja „tylko do odczytu” rozwiązuje ten scenariusz. Po prostu wprowadzając słowo kluczowe tylko do odczytu w deklaracjach, zachowujemy elastyczną inicjalizację, jednocześnie zapobiegając pomijaniu 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 = r;
        green = g;
        blue = b;
    }
}

Warto zauważyć, że stałe elementy są zawsze statyczne, podczas gdy element tylko do odczytu może być statyczny lub nie, tak jak zwykłe pole.

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

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

a inny programista napisał kod, który polegał na A:

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

Czy generowany kod może polegać na tym, że AC jest stałą czasową kompilacji? Czyli użycie AC można po prostu zastąpić wartością 0? Jeśli powiesz „tak”, oznacza to, że twórca A nie może zmienić sposobu inicjalizacji AC - wiąże to ręce twórcy A bez pozwolenia. Jeśli powiesz „nie” w tym pytaniu, ważna optymalizacja zostanie pominięta. Być może autor A jest przekonany, że AC zawsze będzie wynosić zero. Użycie zarówno const, jak i readonly pozwala twórcy A określić intencję. To zapewnia lepsze zachowanie wersjonowania, a także lepszą wydajność.

Ramesh Rajendran
źródło
1

Tylko do odczytu: Wartość zostanie zainicjowana tylko raz z konstruktora klasy.
const: można zainicjować w dowolnej funkcji, ale tylko raz

donstack
źródło
1

Różnica polega na tym, że wartość statycznego pola tylko do odczytu jest ustawiana w czasie wykonywania, więc może mieć inną wartość dla różnych wykonań programu. Jednak wartość stałego pola jest ustawiona na stałą czasową kompilacji.

Pamiętaj: W przypadku typów referencji, w obu przypadkach (statyczny i instancja), modyfikator tylko do odczytu uniemożliwia przypisanie nowego odwołania do pola. W szczególności nie czyni niezmiennego obiektu wskazywanym przez odniesienie.

Szczegółowe informacje można znaleźć w C # Często zadawane pytania na ten temat: http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx

Yonatan Nir
źródło
1

Zmienne stałe są deklarowane i inicjowane w czasie kompilacji. Wartości nie można zmienić po totemach. Zmienne tylko do odczytu zostaną zainicjowane tylko ze statycznego konstruktora klasy. Tylko do odczytu jest używany tylko wtedy, gdy chcemy przypisać wartość w czasie wykonywania.

Omar AMEZOUG
źródło
1

Const : Bezwzględna wartość stałą w czasie życia aplikacji.

Tylko do odczytu : Można to zmienić w czasie wykonywania.

Duże oczy
źródło
1
Twoja definicja „tylko do odczytu”, którą można zmienić, jest błędna. Myślę, że przez „zmianę” miałeś na myśli „set”, na przykład „można go ustawić w czasie wykonywania”.
Ahmed
0

Jedną rzecz do dodania do tego, co ludzie powiedzieli powyżej. Jeśli masz zestaw zawierający wartość tylko do odczytu (np. Readonly MaxFooCount = 4;), możesz zmienić wartość, którą wywołują zestawy, wysyłając nową wersję tego zestawu o innej wartości (np. Readonly MaxFooCount = 5;)

Ale w przypadku const będzie on składany w kodzie dzwoniącego podczas kompilacji dzwoniącego.

Jeśli osiągnąłeś ten poziom biegłości w C #, jesteś gotowy na książkę Billa Wagnera, Skuteczny C #: 50 konkretnych sposobów na poprawę twojego C #, który szczegółowo odpowiada na to pytanie (i 49 innych rzeczy).

Anthony
źródło