2016-01-15 2 views
2

Мы знаем немало вещей о константах:Почему C# постоянных замещенные

  • значение должно быть известно во время компиляции
  • значение не может быть изменено во время выполнения
  • они проталкиваются внутри объявляющего узла метаданные
  • все вхождений заменяются своим значением в IL
  • они могут создать серьезные проблемы кросс сборки версий
  • они не потребляют динамическую память, так как их значения подставляются в IL коде
  • константы могут быть только примитивные типы + любой тип ссылки обнуляются (MSDN не хватает упоминания этой части)

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

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

CLR через C# должен был дать мне чрезмерный ответ, но он просто не сделал этого.

+1

Поскольку они являются константами, его более эффективно испускают код, который будет в конечном счете превратился в 'мов топора, 1234h' изначально, в конечном счете быстрее и эффективнее, чем делать, если поиск все время. Непосредственная адресация быстрее, чем косвенная адресация – MickyD

+0

_ «они могут создать серьезную проблему с версией перекрестного монтажа» _ - только если вы не перекомпилируете все.Как правило, люди должны использовать сервер сборки в любом случае в этот день и в возрасте должного усердного TDD; и серверы CI, а не развертывать из вашего окна DEV, что является единственным способом, я могу думать о том, где вы столкнулись с такой проблемой. – MickyD

+0

«изначально в конечном счете быстрее и эффективнее, чем просмотр постоянно» Bytecode не должен постоянно искать значение. По-моему, при компиляции в IL можно было бы заменить постоянные значения при jitting на байтовый код. Производительность не будет проблемой, так как каждый сборщик должен получить доступ к определяющей сборке один раз, когда будет включен. И вот точка, в которой я изящно противоречу себе :) Таким образом, почти каждое возникновение должно быть просмотрено и заменено на байт-код, поскольку джиттинг обычно происходит на уровне метода. –

ответ

0

У констант есть проблема, и вы назвали ее: «все вхождения заменены ее значением в IL».

Представьте, что у вас есть решение с двумя проектами, консольное приложение (проект A) и базовая DLL (проект B), которые вы используете для DAL/Infrastructure, например.

В вашем проекте B вы определяете TaxRate константы как межды со значением 10, и вы ссылаетесь вашим постоянным в проекте А.

Вы строите (и все константы вхождение будет заменено на значении «10 ", в Иллинойсе.), и вы развертываете свое приложение.

Позже TaxRate изменится на 15 и вы скомпилируете только проект B и замените только DLL в существующем приложении - это будет работать, правильно?

Да и нет. Он будет работать, потому что у вас не будет ошибок - единственное, что изменилось, это значение int. Но в вашем консольном приложении, когда вы ожидаете получить значение 15, вы получите значение 10. Почему? Поскольку постоянное значение было заменено во всех ваших проектах при первом создании приложения, и вы заменили только DLL Project B, а не проект A.

В этом случае, если вы перейдете на общедоступный readonly int, вы будете не имеет этой проблемы.

Надеется, что это помогает,

+0

Я не уверен, что сценарий, описанный вами и намеченный OP, где вы делаете изменения в одной сборке, но не в состоянии перекомпилировать и повторно развернуть все сборки, возможно, не реалистичен и не ответственен. Я не уверен, согласен ли я с стратегией «public readonly int», поскольку он, возможно, устраняет симптом и не устраняет причину. то есть неспособность перестроить все на сервере CI. – MickyD

+0

Прошу прощения, но этот ответ не объясняет реальную причину, почему замещение происходит вообще. –

+0

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

Смежные вопросы