Dlaczego nie mogę mieć „public static const string S =” stuff ”; w mojej klasie?

321

Podczas próby skompilowania mojej klasy pojawia się błąd:

Stała 'NamespaceName.ClassName.CONST_NAME'nie może być oznaczona jako statyczna.

na linii:

public static const string CONST_NAME = "blah";

Mógłbym to robić cały czas w Javie. Co ja robię źle? I dlaczego mi to nie pozwala?

jjnguy
źródło

Odpowiedzi:

583

constObiekt jest zawsze static.

Joel Coehoorn
źródło
2
const powoduje, że zmienna jest stała i nie można jej zmienić.
Samuel
6
@ jinguy: const z natury oznacza static - jeśli masz const, jest już statyczny i dlatego static nie musi być ani nie może być określony.
John Rudy
8
@jjnguy: Dlaczego? readonly jest w rzeczywistości bardziej elastyczny niż wersja Java dla zmiennych - możesz ustawić go tyle razy, ile chcesz w konstruktorze, ale nie gdzie indziej. To może być bardzo przydatne.
Jon Skeet
67
Stałe są wstawiane w czasie kompilacji i nie są obecne w obiekcie typu statycznego w czasie wykonywania. Statyka nie jest wstawiana i żyje wewnątrz obiektu tekstowego. Dodam to tylko dlatego, że nikt nie wspomniał o różnicy ...
3
Są one nadal obecne w czasie wykonywania - możesz do nich dotrzeć z refleksją, na przykład (z GetField).
Jon Skeet
32

Element stały jest uznawany przez kompilator za statyczny, jak również implikuje semantykę wartości stałej, co oznacza, że ​​odniesienia do stałej mogą zostać wkompilowane w kod używający jako wartość elementu stałego, zamiast odwołania do elementu.

Innymi słowy, stały element zawierający wartość 10 może zostać skompilowany do kodu, który używa go jako liczby 10, zamiast odwołania do stałego elementu.

Różni się to od statycznego pola tylko do odczytu, które zawsze będzie kompilowane jako odniesienie do pola.

Uwaga, to jest przed JIT. Kiedy JIT'ter wchodzi w grę, może skompilować oba te elementy do kodu docelowego jako wartości.

Lasse V. Karlsen
źródło
Bardzo ważny punkt, że skompilowany kod zakłada, że ​​stała wartość nie zmieni się w przyszłej wersji.
PJTraill,
6

C # constto dokładnie to samo co Java, tyle finalże absolutnie zawsze static. Moim zdaniem tak naprawdę nie jest konieczne, aby constzmienna nie była static, ale jeśli potrzebujesz uzyskać dostęp do constzmiennej w staticinny sposób, możesz:

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;
    }    
}

Cóż, teraz zdaję sobie sprawę, że to pytanie zostało zadane 4 lata temu, ale ponieważ włożyłem około 2 godzin pracy, polegającej na wypróbowaniu różnego rodzaju odpowiedzi i formatowania kodu, w tej odpowiedzi wciąż go publikuję. :)

Ale, dla przypomnienia, nadal czuję się trochę głupio.

Meowmaritus
źródło
4
O ile mi wiadomo, Java finalzachowuje się dokładnie jak C # readonlyi wcale nie tak const.
Ben Voigt
@jjnguy Dzięki za edycję; Naprawdę nie wiem, dlaczego wybrałem to oryginalne sformułowanie.
Meowmaritus
6

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

... Ponadto, chociaż pole const jest stałą czasu kompilacji , pole tylko do odczytu może być użyte do stałych środowiska wykonawczego ...

Tak więc użycie static w polach const jest jak próba uczynienia zdefiniowanego (za pomocą #define) static w C / C ++ ... Ponieważ jest zastępowana wartością w czasie kompilacji, oczywiście jest inicjowana raz dla wszystkich instancji (= static) .

uriel
źródło
2

const jest podobny do static możemy uzyskać dostęp do obu zmiennych z nazwą klasy, ale diff jest zmienne statyczne można modyfikować, a const nie.

soujanya
źródło