Warum kann ich in meiner Klasse nicht "public static const string S =" stuff "haben?

321

Beim Versuch, meine Klasse zu kompilieren, wird folgende Fehlermeldung angezeigt:

Die Konstante 'NamespaceName.ClassName.CONST_NAME'kann nicht als statisch markiert werden.

an der Linie:

public static const string CONST_NAME = "blah";

Ich könnte das die ganze Zeit in Java tun. Was mache ich falsch? Und warum lässt es mich das nicht tun?

jjnguy
quelle

Antworten:

583

Ein constObjekt ist immer static.

Joel Coehoorn
quelle
2
const macht die Variable konstant und kann nicht geändert werden.
Samuel
6
@jinguy: const bedeutet von Natur aus statisch - wenn Sie eine const haben, ist diese bereits statisch, und static muss daher nicht angegeben werden oder kann nicht angegeben werden.
John Rudy
8
@jjnguy: Warum? readonly ist tatsächlich flexibler als Javas final für Variablen - Sie können es im Konstruktor so oft festlegen, wie Sie möchten, aber nicht anderswo. Das kann sehr praktisch sein.
Jon Skeet
67
Consts werden zur Kompilierungszeit eingefügt und sind zur Laufzeit nicht im statischen Typobjekt vorhanden. Statik ist nicht inline und befindet sich innerhalb des Typobjekts. Ich füge dies hinzu, nur weil niemand den Unterschied erwähnt hat ...
3
Sie sind zur Ausführungszeit noch vorhanden - Sie können sie beispielsweise mit Reflexion (mit GetField) erreichen.
Jon Skeet
32

Ein const-Element wird vom Compiler als statisch betrachtet und impliziert eine Konstantwertsemantik. Dies bedeutet, dass Verweise auf die Konstante anstelle eines Verweises auf das Element in den using-Code als Wert des konstanten Elements kompiliert werden können.

Mit anderen Worten, ein const-Element, das den Wert 10 enthält, wird möglicherweise in Code kompiliert, der ihn als Nummer 10 verwendet, anstatt auf das const-Element zu verweisen.

Dies unterscheidet sich von einem statischen schreibgeschützten Feld, das immer als Referenz auf das Feld kompiliert wird.

Beachten Sie, dass dies Pre-JIT ist. Wenn der JIT'ter ins Spiel kommt, kompiliert er möglicherweise beide als Werte in den Zielcode.

Lasse V. Karlsen
quelle
Sehr wichtiger Punkt, dass der kompilierte Code davon ausgeht, dass sich der konstante Wert in einer zukünftigen Version nicht ändert.
PJTraill
6

C # constist genau das gleiche wie Java final, außer dass es absolut immer ist static. Meiner Meinung nach muss eine constVariable nicht unbedingt nicht sein static, aber wenn Sie nicht nur auf eine constVariable staticzugreifen müssen, können Sie Folgendes tun:

class MyClass
{    
    private const int myLowercase_Private_Const_Int = 0;
    public const int MyUppercase_Public_Const_Int = 0;

    /*        
      You can have the `private const int` lowercase 
      and the `public int` Uppercase:
    */
    public int MyLowercase_Private_Const_Int
    {
        get
        {
            return MyClass.myLowercase_Private_Const_Int;
        }
    }  

    /*
      Or you can have the `public const int` uppercase 
      and the `public int` slighly altered
      (i.e. an underscore preceding the name):
    */
    public int _MyUppercase_Public_Const_Int
    {
        get
        {
            return MyClass.MyUppercase_Public_Const_Int;
        }
    } 

    /*
      Or you can have the `public const int` uppercase 
      and get the `public int` with a 'Get' method:
    */
    public int Get_MyUppercase_Public_Const_Int()
    {
        return MyClass.MyUppercase_Public_Const_Int;
    }    
}

Nun, jetzt ist mir klar, dass diese Frage vor 4 Jahren gestellt wurde, aber da ich ungefähr 2 Stunden Arbeit, bestehend aus dem Ausprobieren aller möglichen Arten der Beantwortung und Code-Formatierung, in diese Antwort gesteckt habe, poste ich sie immer noch. :) :)

Aber fürs Protokoll, ich fühle mich immer noch irgendwie albern.

Meowmaritus
quelle
4
Soweit ich das beurteilen kann, finalverhält sich Java genau wie C # readonlyund überhaupt nicht wie const.
Ben Voigt
@jjnguy Danke für die Bearbeitung; Ich weiß nicht genau, warum ich diesen ursprünglichen Wortlaut gewählt habe.
Meowmaritus
6

Von MSDN: http://msdn.microsoft.com/en-us/library/acdd6hb7.aspx

... Während ein const-Feld eine Konstante zur Kompilierungszeit ist, kann das schreibgeschützte Feld auch für Laufzeitkonstanten verwendet werden ...

Die Verwendung von static in const-Feldern ist also wie der Versuch, eine definierte (mit #define) static in C / C ++ zu erstellen ... Da sie in der Kompilierungszeit durch ihren Wert ersetzt wird, wird sie natürlich einmal für alle Instanzen initiiert (= static). .

Uriel
quelle
2

const ist ähnlich wie static. Wir können auf beide Variablen mit dem Klassennamen zugreifen, aber diff ist statisch. Variablen können geändert werden und const nicht.

Soujanya
quelle