Почему const int неявно преобразуется в байт, а переменная int - нет? - PullRequest
6 голосов
/ 29 января 2012

Следующая программа не будет компилироваться:

   class Program
   {
      static void Main(string[] args)
      {
         int x = 50;
         Byte[] y = new Byte[3] { x, x, x };
      }
   }

Не удивительно, что я получу ошибку Cannot implicitly convert type 'int' to 'byte'

Однако, если я сделаю x const, то она будетcompile:

   class Program
   {
      public const int x = 50;

      static void Main(string[] args)
      {
         Byte[] y = new Byte[3] { x, x, x };
      }
   }

Мне интересно, что здесь происходит.Если int не может быть неявно приведен к байту, компилятор создает «байтовую» версию моего const на лету или компилирует его так, как если бы я поместил явное приведение, так как он считает постоянное значение«безопасно» для байта?Возможно, компилятор интерпретирует это так, как если бы я написал:

Byte[] y = new Byte[3] { 50, 50, 50 };

Так как это допустимо, мне более любопытно, что компилятор здесь делает.

Ответы [ 6 ]

6 голосов
/ 29 января 2012

Я отсылаю вас к разделу 6.1.9 спецификации C # 4, в котором говорится:

Константное выражение типа int может быть преобразовано в тип sbyte, byte, short, ushort, uint или ulong при условии, что значение константного выражения находится в пределах диапазона целевого типа.

Ваш вопрос был:

создает ли компилятор "байтовую" версию моего const на лету или компилирует его так, как если бы я поместил явное приведение, так как он считает постоянное значение "безопасным" для байта?

Я не понимаю разницу между этими двумя вещами; для меня они звучат как одно и то же.

5 голосов
/ 29 января 2012

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

В вашем третьем фрагменте все эти три 50 равны System.Int32. Наведите указатель мыши и прочитайте подсказку в Visual Studio. Почему здесь нет ошибки компилятора? Поскольку компилятор знает значение во время компиляции и знает, что оно будет помещаться в byte.

2 голосов
/ 29 января 2012

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

1 голос
/ 29 января 2012

Константы «запекаются» во время компиляции.

Одним примечательным следствием компиляции констант является то, что, если вы компилируете сборку, она будет использовать значения констант во время компиляции. Если позднее вы выполните привязку к другой версии сборки во время выполнения, она будет использовать исходные константы, даже если они изменились в новой версии сборки. Это также относится, в частности, к константам Enum. Мораль этой истории заключается в том, что (публичные) постоянные ценности действительно должны быть постоянными; если есть какая-либо возможность значимого изменения, используйте вместо этого статическое поле только для чтения.

0 голосов
/ 29 января 2012

ответ таков: потому что const становится литералом подпрограммой препроцессора и интерпретируется как «код», а переменная - нет.

0 голосов
/ 29 января 2012

В основном это сводится к тому, что различие заключается в том, что когда компилятор знает значение во время компиляции, тогда приведение допустимо, если значение для большего числового типа находится в допустимом диапазоне для меньшего числового типа.Если компилятор не знает, так ли это, то это не разрешено, если вы не используете явное приведение, чтобы убедиться, что оно будет в этом диапазоне при запуске программы.

Хотя мы знаем,что значение x вряд ли изменится между его объявлением и использованием, поскольку для того, чтобы знать наверняка, что оно не изменится, требуется сложный анализ, который компилятор не пытается (и на самом деле его невозможно будет всегда исправить).Если переменная не является константой, то компилятор не делает выводов относительно ее фактического значения.

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