Постоянное значение не изменяется при перекомпиляции ссылочной сборки

У меня есть этот код в сборке:

public class Class1
{
    public const int x = 10;
}

и в другой сборке у меня есть:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Class1.x);
        Console.ReadKey();
    }
}

Конечно, вывод был 10, но затем я изменил x в 20:

public class Class1
{
    public const int x = 20;
}

Я перекомпилировал сборку и переместил ее в каталог bin моей программы командной строки. Однако вывод моей программы все еще был 10, пока я не скомпилировал сборку, содержащую main function.

Почему это происходит?

12 голосов | спросил No Idea For Name 15 J0000006Europe/Moscow 2014, 12:06:15

2 ответа


0

Значения констант в C # встроены там, где они используются. То есть строка Console.WriteLine(Class1.x); будет скомпилирована в Console.WriteLine(10);. Сгенерированный IL-код будет выглядеть так:

  .entrypoint
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldc.i4.s   10  // here just integer value 10 is loaded on stack
  IL_0003:  call       void [mscorlib]System.Console::WriteLine(int32)

Там не будет никакой ссылки на Class1. Таким образом, пока вы не перекомпилируете сборку Main, она будет иметь встроенное значение 10. MSDN имеет предупреждение об этом случае использования констант:

  

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

Они упоминают, что константные выражения оцениваются только во время компиляции. То есть Class1.x будет оцениваться при компиляции Main время для значения 10. И без перекомпиляции это значение не изменится. Но, к сожалению, это не объясняет причину такого поведения (по крайней мере, мне).

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

ответил Sergey Berezovskiy 15 J0000006Europe/Moscow 2014, 12:07:35
0

Это метод, называемый константное сворачивание , используемый при компиляции. Короче говоря, компилятор ищет значения, которые могут быть определены во время компиляции, вычисляет эти значения и записывает их напрямую в исполняемый файл. Это ускоряет выполнение окончательного машинного кода. Этот метод применим и ко многим другим компилируемым языкам, таким как C, C ++.

ответил kevin 15 J0000006Europe/Moscow 2014, 12:48:48

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132