Статическое чтение только против const - разные сборки POV? - PullRequest
17 голосов
/ 02 февраля 2012

Есть много вопросов по этому вопросу, но ни один (кроме один, но все же короткий ) не имеет отношения к следующему сценарию.

Из книги C # 4:

enter image description here

Марк также писал:

если вы измените значение const, вам нужно перестроить все клиенты

Вопрос:

1) Почему это? static readonly и const - static?

2) Где на самом деле значения сохраняются?

3) Как создание поля static readonly на самом деле solve этой проблемы "за кадром"?

Ответы [ 5 ]

24 голосов
/ 02 февраля 2012

если вы измените значение const, вам нужно перестроить все клиенты

Это не правильное решение. Если вы измените значение const, то оно не будет константой. Константы по определению вещи, которые никогда не меняют своего значения . Идея, что вы бы изменили значение константы , означает, что вы делаете что-то логически невозможное, и поэтому, конечно, все сломается; вы делаете то, что, как вы сказали, вы не сделаете. Если вы будете лгать компилятору, и это причиняет вам боль, тогда перестанете врать компилятору .

Цена на золото не является постоянной. Название вашего банка не является константой. Номер версии вашей программы не является константой. Эти вещи меняются, поэтому не делают их постоянными . Константы - это такие вещи, как пи, или число протонов в атоме золота.

Переменные - это вещи, которые могут варьироваться - поэтому они называются «переменными». Константы - это вещи, которые остаются ... постоянными. Если он может меняться, сделайте его переменным. Если оно постоянное, сделайте его постоянным. Это так просто.

почему это? статические readonly и const статические

Конечно. Какое это имеет отношение к этому? «статический» в C # означает «именованный элемент связан с типом, а не с каким-либо конкретным экземпляром типа». («Static» - поэтому плохой выбор терминов; VB делает это лучше с «shared».)

Является ли имя связанным с типом или экземпляром, не имеет отношения к вопросу о том, относится ли имя к константе или переменной .

где на самом деле значения сохраняются в обоих статических readonly vsconst?

Когда вы используете постоянное значение, значение «запекается» везде, где оно используется. Это безопасно , потому что оно никогда не изменится . Он никогда не изменится , потому что он постоянен , и это то, что означает "константа".

Когда вы используете переменную, значение переменной ищется во время выполнения каждый раз. «Только чтение» означает, что «эта переменная может быть изменена только в конструкторе класса или инициализаторе поля». Это все еще переменная. (*)

как сделать поле статическим только для чтения - на самом деле решить эту проблему за сценой?

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


(*) Поля только для чтения считаются непостоянными значениями вне конструктора, так что поле только для чтения типа изменяемого значения не может быть изменено, и поэтому вы не можете взять ref в поле только для чтения, а затем измените ссылку.

22 голосов
/ 02 февраля 2012

нет, const - это const, а не static - это особый случай с другими правилами;он только установлен во время компиляции (не во время выполнения) и обрабатывается по-другому

суть здесь в следующем:

var foo = SomeType.StaticValue;

против

var bar = SomeType.ConstValue;

в случае first , оно считывает значение во время выполнения из SomeType, то есть через ldsfld;однако во втором случае это компилируется в значение , т. е. если ConstValue равно 123, то второе идентично :

var bar = 123;

во время выполнения, тот факт, что он произошел от SomeType , не существует , так как значение (123) было оценено компилятором и сохранено.Следовательно, для получения новых значений требуется перестройка.

Изменение на static readonly означает, что «загрузить значение из SomeType» сохраняется.

Итак, следующее:

static int Foo()
{
    return Test.Foo;
}
static int Bar()
{
    return Test.Bar;
}
...
static class Test
{
    public static readonly int Foo = 123;
    public const int Bar = 456;
}

компилируется как:

.method private hidebysig static int32 Bar() cil managed
{
    .maxstack 8
    L_0000: ldc.i4 0x1c8
    L_0005: ret 
}

.method private hidebysig static int32 Foo() cil managed
{
    .maxstack 8
    L_0000: ldsfld int32 ConsoleApplication2.Test::Foo
    L_0005: ret 
}

Обратите внимание, что в Bar ldc загружает значение напрямую (0x1c8 == 456) с помощью Test полностью исчезло.

Для полноты const является , реализованным со статическим полем, но - это поле literal , означающее: вычисляется в компиляторе,не во время выполнения.

.field public static literal int32 Bar = int32(0x1c8)
.field public static initonly int32 Foo
6 голосов
/ 02 февраля 2012

1) const просто разрешается во время компиляции с указанным вами значением. Пока static readonly является статической переменной.

2) static значения обычно хранятся в специальной области в куче, которая называется High Frequency Heap . Как я уже говорил ранее, константы подставляются во время компиляции.

3) выполнение этого static readonly решит проблему, потому что вы будете читать значение переменной во время выполнения, а не значение, предоставленное во время компиляции.

4 голосов
/ 02 февраля 2012

Вы уже ответили на свой вопрос с изображением, на которое вы ссылались. const поля будут скомпилированы («встроены») в сборку - как простой поиск и замена. static readonly означает нормальное поле, которое не может быть изменено и существует только один раз в памяти, но на которое все еще ссылается местоположение в памяти.

В .NET Framework константам назначается не область памяти, а вместо этого считаются значения. Поэтому вы никогда не сможете назначить постоянная, но загрузка постоянной в память более эффективна потому что он может быть введен непосредственно в поток команд. это исключает любые обращения к памяти вне памяти, улучшая местность ссылки. http://www.dotnetperls.com/optimization

0 голосов
/ 23 сентября 2013

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

...