Sind öffentliche Konstanten „schlecht“?

38

Ist das:

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

schlimmer als das:

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

Beide können auf dieselbe Weise referenziert werden:

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

Der zweite hat jedoch den Schutz eines Eigentums. Aber wie viel besser ist das wirklich als ein const?

Ich habe immer wieder gelernt, wie gefährlich es ist, öffentliche Felder zu haben. Als ich also einen Code sah, der diese Konstanten in öffentlichen Feldern verwendete, begann ich sofort damit, sie in Eigenschaften umzugestalten. Aber auf halbem Weg fragte ich mich, welchen Nutzen es hatte, die statischen Eigenschaften gegenüber den Konstanten zu haben.

Irgendwelche Ideen?

Vaccano
quelle
1
Öffentliche Konstanten, die auf diese Weise verwendet werden, sind in Ordnung. Die Verwendung von Eigenschaften auf diese Weise ist übertrieben.
Bernard
2
Haben Sie darüber nachgedacht, das Schlüsselwort readonly zu verwenden ? ReadOnly bietet Ihnen die übersichtlichere Syntanx einer Konstante ohne die in vielen Beiträgen genannten Probleme.
Matt Raffel
Könnte auch tun ... public static readonly type constantName = 0;
Snoop

Antworten:

56

In C # ist es aus keinem der in diesem Thread genannten Gründe sehr schlecht.

Öffentliche Konstanten in C # werden in referenzierende Assemblys eingebunden. Wenn Sie also eine SomeOtherClass in einer separaten Assembly haben, die auf SomeString in MyClass verweist, enthält die für SomeOtherClass generierte CIL eine fest codierte Zeichenfolge "SomeValue".

Wenn Sie die DLL, die MyClass, aber nicht SomeOtherClass enthält, erneut bereitstellen und die Konstante ändern, enthält SomeOtherClass nicht das, was Sie glauben, sondern den ursprünglichen Wert.

Wenn Sie zu 100% sicher sind, dass es sich um eine universelle Konstante wie Pi handelt, machen Sie sich verrückt. sonst vorsichtig treten.

Hier ist eine bessere Erklärung: https://stackoverflow.com/questions/55984/was-ist-der- Unterschied-zwischen-konstante-und-nur-schon

brian
quelle
3
@Oded, aber der gleiche Unterschied besteht zwischen einer constschreibgeschützten Eigenschaft. constist in die aufrufende Assembly eingebunden, schreibgeschützte Eigenschaften jedoch nicht.
Svick
1
Das wusste ich nicht. Es ist ein weiterer Beweis dafür, dass öffentliche Felder schlecht sind. Ich denke, dass sogar das "sichere" Beispiel für Pi eine schlechte Idee ist (Was ist, wenn ein Entwickler mehr oder weniger genaue Stellen für Pi haben möchte? Und die Änderung an der Baugruppe vornimmt, ohne dieses Problem zu kennen.) Ich habe über 40 Baugruppen in meiner Lösung und ich könnte sehen, dass dies uns wirklich beißt, wenn wir nicht vorsichtig sind.
Vaccano
2
Kommt dieses "Kopieren" in anderen Teilen von C # vor? (dh Aufzählungen)
Vaccano
2
Ja, die Kopie kommt vor. Dies ist normalerweise kein Problem. Wenn Ihr Code jedoch den numerischen Wert einer Aufzählung verwendet und in der in dieser Frage beschriebenen Weise geändert wird, kann dies zu Problemen führen.
Vaccano
1
Dies ist einer der Hauptgründe, warum constin C # dumm ist. Wir brauchen bessere Unterstützung für
immutables
22

Das Ändern eines Felds in eine Eigenschaft ist eine grundlegende Änderung. Sie verlieren die Binär-, Quell- und Reflektionskompatibilität.

Und dazu:

  • Es gibt eine differenziertere Zugriffskontrolle mit Eigenschaften. Müssen sie öffentlich abrufbar sein, möchten sie aber wirklich nur mit geschütztem Zugriff eingerichtet werden? Kein Problem (zumindest ab C # 2).
  • Möchten Sie in den Debugger einbrechen, wenn sich der Wert ändert? Fügen Sie einfach einen Haltepunkt in den Setter ein.
  • Möchten Sie alle Zugriffe protokollieren? Fügen Sie dem Getter einfach die Protokollierung hinzu.
  • Eigenschaften werden für die Datenbindung verwendet. Felder sind nicht.

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

Trotzdem sehe ich nicht, wie Konstanten wirklich davon betroffen sind (insbesondere, wenn Sie keine der oben genannten Funktionen benötigen), es sei denn, Ihre API ändert sich so, dass sie keine Konstanten mehr sind.

Robert Harvey
quelle
11

Die Gefahr von öffentlichen Feldern besteht darin, dass sie veränderlich sind und sich die zugrunde liegende Implementierung ändern kann.

Wenn es zu einem kommt, constist dies normalerweise kein Problem (ähnlich wie bei öffentlichen Aufzählungen) - es sei denn, Sie glauben, dass das constals veränderlich enden wird und dass Sie irgendwann eine Kapselung um den Accessor benötigen (sagen wir, um zu protokollieren, wie oft es ausgesehen hat) up), können Sie es genauso gut als Publikum behalten const.

Oded
quelle
1

Eine Konstante sind Daten. Eigenschaften implizieren die Möglichkeit des Verhaltens, wenn Sie den Wert "betrachten".

Das Bündeln des Verhaltens (oder der zukünftigen Möglichkeit davon) mit konstanten Daten ist völlig falsch. Für die meisten Systeme ist es nicht wirklich wichtig, aber es kann.

Nehmen wir an, der Wert ist "PI" und wird ausgiebig in den Berechnungen des Systems verwendet. Wenn Sie es hinter Eigenschaften setzen, werden Client-Programmierer gezwungen, defensiv zu programmieren. Sie müssen den Wert in eine doppelte Konstante zuweisen. Wenn sie nicht überlistet werden, könnte in der nächsten Version der Bibliothek ein unerwünschtes "Verhalten" hinter der Eigenschaft eingeführt werden. Das Verhalten der Eigenschaft (wenn sie sich in einer kompilierten Bibliothek befindet) ist unbekannt. Vielleicht funktioniert es im Test gut, aber es könnte versteckten Code geben, der ausgeführt wird, wenn eine spezielle Bedingung erfüllt ist. Dies ist keine vorzeitige Optimierung. Besonders für ein Echtzeitsystem hängt das Leben der Menschen davon ab.

Die Client-Programmierer können sogar die Sicherheit einer Konstante verlieren, da die Sprache es ihnen möglicherweise nicht erlaubt, einen Eigenschaftswert in ihre doppelte Konstante einzugeben.

Wenn Programmierer gezwungen sind, Ihren Eigenschaftswert ihrer eigenen Konstante zuzuweisen, heben sie effektiv jedes Verhalten auf, das Sie mit Ihrer Eigenschaft erreichen wollten.

Echte konstante Daten brauchen oder wollen keine Kapselung.

Lord Tydus
quelle