Gibt es einen Unterschied zwischen privaten konst und privaten Nur-Lese-Variablen in C #?

StackOverflow https://stackoverflow.com/questions/410723

  •  03-07-2019
  •  | 
  •  

Frage

Gibt es einen Unterschied zwischen einer private const Variable mit oder einer private static readonly Variable in C # (anders als mit der const einem Compiler-Ausdruck zuweisen)?

Da sie beide privat sind, gibt es keine Verknüpfung mit anderen Bibliotheken. So würde es keinen Unterschied machen? Kann es einen Performance-Unterschied zum Beispiel machen? Internierten Strings? Etwas Ähnliches?

War es hilfreich?

Lösung

Nun können Sie consts in Attribute verwenden, da sie als Kompilierung existieren. Sie können nicht den Wert eines statischen Nur-Lese-Variable vorhersagen, da die .cctor es von der Konfiguration usw. initialisieren kann.

Im Hinblick auf die Nutzung sind Konstanten in den Aufrufcode verbrannt. Das bedeutet, dass, wenn Sie eine Bibliothek neu kompilieren dll einen Öffentlichkeit Konstante zu ändern, aber nicht die Verbraucher ändern, dann hat er die Verbraucher immer noch den ursprünglichen Wert verwenden. Mit einem Nur-Lese-Variable wird dies nicht passieren. Die Flip dafür ist, dass Konstanten sind (sehr, sehr leicht) schneller, da sie einfach den Wert lädt (anstatt es de-Referenz).

Re Internierung; obwohl Sie dies manuell tun können, ist dies am häufigsten ein Compiler / runtime-Funktion von Literalen; wenn Sie ein Nur-Lese-Feld über eine wörtliche init:

someField = "abc";

dann wird der "abc" interniert werden. Wenn Sie es von Config lesen, wird es nicht sein. Da ein konstanter String muss eine Literal sein, wird es auch interniert werden, aber es ist anders zugegriffen: wieder, aus dem Feld zu lesen ist eine de-Referenz, sondern als ein ldstr .

Andere Tipps

Tatsächlich können die beiden Typen nicht geändert werden, nachdem sie initialisiert wurden, aber es gibt einige Unterschiede zwischen ihnen:

  • ‚const‘ muss initialisiert werden, wo sie (bei der Kompilierung) deklariert sind, während ‚Read-only‘ initialisiert werden kann, wo sie deklariert oder innerhalb des Konstruktors (ar Laufzeit).

Zum Beispiel konst in dieser Situation verwendet werden könnte:

public class MathValues
{
  public const double PI = 3.14159;
}

Und nur lesbar wäre für diesen Fall besser sein:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

oder

public class Person
{
    public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
  • ‚const‘ ist statisch, so dass es zwischen allen Instanzen dieser Klasse geteilt wird und kann direkt (wie MathValues.PI) zugegriffen werden, während ‚Read-only‘ nicht statisch ist. Als Folge ist eine Erklärung wie 'static const' illegal, weil const statisch ist, sondern 'static nur lesbar' ist legal

  • 'const' kann nur Integral-Typ (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, dezimal, Bool, oder string), eine Aufzählung halten, oder ein Verweis auf null (keine Klassen oder Strukturen, weil sie zur Laufzeit initialisiert, mit dem ‚neuen‘ Schlüsselwort), während ‚Read-only‘ komplexe Typen halten kann, Strukturen oder Klassen (durch das neue Schlüsselwort bei der Initialisierung verwendet wird), kann aber nicht Aufzählungen halten

Etwas über Konstanten zu beachten ist sie in der ausführbaren Datei tatsächlich gespeichert, so viele von ihnen zu erklären wird Ihre ausführbare Dateigröße erhöhen.

Normalerweise ist dies kein großes Problem, aber ein Freund von mir in der Firma gearbeitet, die ein erzwungene „alles muss const sein“ -Regel und verwalten deutlich ihre kompilierte ausführbare Größe zu erhöhen.

Hier sind die Unterschiede zwischen C # .NET const Nur-Lese und statische Nur-Lese Felder (von dieser Artikel ).

Konstanten :

  • Static standardmäßig
  • Müssen Kompilierung Zeitwert (h .: Sie haben „A“ + „B“ kann aber nicht Methodenaufrufe haben)
  • Kann in Attribute verwendet werden
  • in jede Baugruppe kopiert, die sie verwendet (jede Baugruppe eine lokale Kopie des Wertes wird)
  • Könnte innerhalb von Funktionen deklariert werden

Read-only-Instanz Felder :

  • ausgewertet werden, wenn Instanz erstellt
  • haben muss Wert durch die Zeit Konstruktor Ausfahrten

Static Nur-Lese-Felder :

  • ausgewertet, wenn die Ausführung von Code trifft Klassenreferenz (d.h .: neue Instanz erstellt oder statische Methode ausgeführt wird)
  • muss statisch ausgewertet Wert Konstruktor von der Zeit getan haben, ist
  • Sie wollen wirklich nicht Thread auf diese setzen (da statische Konstruktor wird nur in einem Thread ausgeführt werden, und es wird Wert für seine Thread gesetzt, alle anderen Threads diesen Wert haben wird nicht initialisiert)

Es ist bemerkenswerter Unterschied zwischen const und Nur-Lese Felder in C # .Net

const ist standardmäßig statisch und muss mit einem konstanten Wert initialisiert werden, die später nicht mehr geändert werden. Wertänderung wird in Konstrukteuren nicht erlaubt, auch. Es kann nicht mit allen Datentypen verwendet werden. Für Ex-Datetime. Es kann nicht mit Datetime-Datentyp verwendet werden.

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

Nur-Lese kann als statisch deklariert werden, aber nicht notwendig. Keine Notwendigkeit zum Zeitpunkt der Erklärung zu initialisieren. Sein Wert kann mit Konstruktor zugewiesen oder geändert werden. Also, es gibt Vorteile, wenn sie als Instanzklasse Element verwendet. Zwei verschiedene Instanziierung anderen Wert von Nur-Lese-Feld hat. Für die Ex -

class A
{
    public readonly int Id;

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

Dann Nur-Lese-Feld kann mit Sofort spezifischen Werten initialisiert werden, wie folgt:

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

Hier Instanz objOne wird Wert von Nur-Lese-Bereich hat, wie 5 und objTwo hat 10. Welche nicht möglich mit const ist.

Bei der Verwendung? Nicht wirklich. Consts werden bei der Kompilierung ausgewertet, während nur lesbar zur Laufzeit ausgewertet werden. Sie können auch ein Nur-Lese-Variable einen Wert im Konstruktor zuweisen.

Eine weitere Sache. Ich habe dies nicht in den Kommentaren oben, obwohl ich es verpasst haben. Sie können nicht eine konstante Array erstellen.

private const int[] values = new int[] { 1, 2, 3 };

Aber Sie können erstellen sie ein statisches Nur-Lese-Feld verwendet wird.

private static readonly int[] values = new int[] { 1, 2, 3 };

Wenn Sie also einen Array-Konstante benötigen, wie beispielsweise eine Liste der zulässigen Werte, und eine Aufzählung nicht angemessen wäre, dann ist die statische nur lesbar ist der einzige Weg zu gehen. Zum Beispiel, wenn das Array waren von Nullable-Zahlen, wie folgt aus:

private static readonly int?[] values = new int?[] { null, 1, 2, 3 };

Kann nicht , die mit einem konstanten, kann ya?

Der Unterschied besteht darin, dass der Wert eines statischen Nur-Lese-Gebiets zur Laufzeit festgelegt wird, und kann somit durch die Klasse enthält, modifiziert werden, während der Wert eines const Feld zu einer Kompilierung Zeitkonstante eingestellt ist.

Im statischen Nur-Lese-Fall wird die enthaltende Klasse erlaubt es nur zu ändern

in der Variablendeklaration (über eine Variableninitialisierer) im statischen Konstruktor (Instanzkonstruktoren, wenn es nicht statisch ist) typischerweise verwendet, wenn der Typ des Feldes statische Nur-Lese wird nicht in einer const Deklaration erlaubt, oder wenn der Wert nicht zum Zeitpunkt der Kompilierung bekannt.

Instanz Nur-Lese-Felder sind ebenfalls erlaubt.

Beachten Sie, dass Typen als Referenz, in beiden Fällen (statisch und Instanz) der Nur-Lese-Modifikator nur verhindert, dass eine neue Referenz auf das Gebiet von zuweisen. Es ist ausdrücklich nicht unveränderlich macht das Objekt mit dem Bezug hingewiesen.

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

Der Unterschied besteht darin, dass statische schreibgeschützte von der enthaltenden Klasse modifiziert werden können, aber const kann nie geändert werden und muss auf eine Kompilierung Zeitkonstante initialisiert werden. So erweitern Sie auf dem statischen Nur-Lese-Fall ein wenig, kann die Klasse enthält nur modifizieren:

-. In der Variablendeklaration (über eine Variableninitialisierer)

-. Im statischen Konstruktor (Instanzkonstruktoren wenn es nicht statisch ist)


Const Schlüsselwort in C # .NET

Beispiel: public const string abc = “xyz”; nur bei der Deklaration initialisiert. Der Wert wird bei der Kompilierung ausgewertet und kann zur Laufzeit nicht geändert werden. Ein Versuch, es zu ändern, wird ein Übersetzungsfehler verursachen. Konst ist bereits Art statisch. Da Klassen und Strukturen zur Laufzeit mit neuem Schlüsselwort initialisiert werden, können Sie nicht eine Konstante zu einer Klasse oder Struktur festgelegt. Aber, es hat eine der integralen Typen. Nur-Lese-Schlüsselwort in C # .NET

Beispiel: public readonly string abc; Kann in Deklarationscode oder consturctor Code initialisiert werden. Der Wert wird zur Laufzeit ausgewertet. Kann als statisches oder Instanzebene Attribut deklariert werden. Ein Nur-Lese-Feld ein komplexes Objekt mit dem neuen Schlüsselwort zur Laufzeit halten kann.

Read-only-Felder können die Erklärung oder in einem Konstruktor eine Klasse initialisiert entweder werden. Deshalb Nur-Lese-Felder auf den Konstruktor je unterschiedliche Werte haben verwendet .

Ein Nur-Lese-Mitglied kann auch sein für die Laufzeitkonstanten verwendet , wie im folgenden Beispiel:

public static readonly uint currentTicks = (uint)DateTime.Now.Ticks;

Read-only Felder sind nicht implizit statisch, und daher ist die Schlüsselwort static kann (muss) auf einen Nur-Lese-Feld explizit angewendet werden, falls erforderlich. Dies gilt nicht für const Felder erlaubt, die implizit statisch sind.

Read-only-Mitglieder können komplexe Objekte halten, indem Sie das neue Schlüsselwort bei der Initialisierung mit .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top