Почему в моем классе не может быть «public static const string S =» stuff »;

321

При попытке скомпилировать мой класс я получаю сообщение об ошибке:

Константа 'NamespaceName.ClassName.CONST_NAME'не может быть помечена как статическая.

на линии:

public static const string CONST_NAME = "blah";

Я мог бы делать это все время на Java. Что я делаю не так? И почему это не позволяет мне сделать это?

jjnguy
источник

Ответы:

583

constОбъект всегда static.

Джоэл Коухорн
источник
2
const делает переменную постоянной и не может быть изменена.
Самуил
6
@jinguy: const по своей сути означает статический - если у вас есть какой-либо const, он уже статический, поэтому статический не нужно ни указывать, ни указывать.
Джон Руди
8
@jjnguy: почему? readonly на самом деле более гибок, чем финальный Java для переменных - вы можете установить его столько раз, сколько захотите в конструкторе, но не где-либо еще. Это может быть очень удобно.
Джон Скит
67
Констант встроены во время компиляции и не присутствуют в объекте статического типа во время выполнения. Статика не встроена и находится внутри объекта типа. Я добавляю это только потому, что никто не упомянул разницу ...
3
Они все еще присутствуют во время выполнения - вы можете получить их с отражением, например (с GetField).
Джон Скит
98

Из спецификации языка C # (страница PDF 287 или 300 страница PDF):

Несмотря на то, что константы считаются статическими членами, объявление констант не требует и не допускает статический модификатор.

splattne
источник
2
Также доступно здесь: msdn.microsoft.com/en-us/library/aa645749(VS.71).aspx
Лассе В. Карлсен
32

Константный член считается статическим компилятором, а также подразумевает семантику константного значения, что означает, что ссылки на константу могут быть скомпилированы в коде использования в качестве значения константного члена, а не ссылки на член.

Другими словами, член const, содержащий значение 10, может быть скомпилирован в код, который использует его как число 10 вместо ссылки на член const.

Это отличается от статического поля только для чтения, которое всегда будет компилироваться как ссылка на поле.

Обратите внимание, это предварительный JIT. Когда JIT'ter вступает в игру, он может скомпилировать их в целевой код в виде значений.

Лассе В. Карлсен
источник
Очень важный момент, что скомпилированный код предполагает, что постоянное значение не изменится в будущей версии.
PJTraill
6

C # - constэто то же самое, что и Java final, за исключением того, что это абсолютно всегда static. На мой взгляд, не обязательно, чтобы constпеременная была ненулевой static, но если вам нужен constне- staticединственный доступ к переменной , вы можете сделать:

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

Что ж, теперь я понимаю, что этот вопрос задавался 4 года назад, но, поскольку я потратил около 2 часов работы, состоящей из попыток различных способов ответа и форматирования кода, в этот ответ, я все еще публикую его. :)

Но, к сведению, я все еще чувствую себя немного глупо.

Meowmaritus
источник
4
Насколько я могу судить, Java finalведет себя точно так же, как C # readonly, и совсем не так const.
Бен Фойгт
@jjnguy Спасибо за редактирование; Я действительно не знаю, почему я выбрал эту оригинальную формулировку.
Мяумаритус
6

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

... Кроме того, хотя поле const является константой времени компиляции , поле readonly может использоваться для констант времени выполнения ...

Таким образом, использование static в полях const похоже на попытку сделать определенный (с помощью #define) static в C / C ++ ... Поскольку он заменяется своим значением во время компиляции, конечно, он инициируется один раз для всех экземпляров (= static) ,

Уриэль
источник
2

const похож на static, мы можем получить доступ к обоим объектам с именем класса, но diff - это статические переменные, которые можно изменить, а const - нет.

soujanya
источник