Любой экземпляр типа значения, который содержит любую информацию, может быть преобразован в код, который может записать место хранения, в котором он содержится, и ни один экземпляр типа значения не может быть преобразован в код, который не может записать место хранения, в котором он содержится.Эти характеристики делают частные хранилища хранилищ изменяемых типов значений идеальными контейнерами данных во многих сценариях, поскольку они сочетают удобство обновления, вытекающее из изменчивости, с контролем, исходящим из неизменяемости.Обратите внимание, что можно написать код для типа значения таким образом, что невозможно изменить существующий экземпляр без предварительного наличия экземпляра (возможно, вновь созданного временного экземпляра), который содержит требуемые данные, и перезаписи содержимогопервый экземпляр с содержимым последнего, но это не сделает тип значения более или менее изменчивым, чем если бы не было такой возможности.Во многих случаях это просто служит для того, чтобы сделать мутацию неуклюжей и заставить ее выглядеть так, как если бы оператор вроде:
MyKeyValuePair =
new KeyValuePair<long,long>(MyKeyValuePair.Key+1, MyKeyValuePair.Value+1>;
создаст новый экземпляр, но оставит существующий экземпляр без изменений.Если бы KeyValuePair
был неизменным классом, и один поток выполнял MyKeyValuePair.ToString()
, в то время как другой поток выполнял вышеуказанный код, вызов ToString
воздействовал бы либо на старый, либо на новый экземпляр и, таким образом, давал бы оба старых значения.или оба новых значения.Поскольку KeyValuePair
является структурой, вышеприведенный оператор создаст новый экземпляр, но он не заставит MyKeyValuePair
ссылаться на новый экземпляр - он просто будет использовать новый экземпляр в качестве шаблона, поля которого будут скопированыдо MyKeyValuePair
.Если бы KeyValuePair
была изменяемой структурой, наиболее естественное выражение вероятного предполагаемого значения для приведенного выше кода было бы больше похоже на:
MyKeyValuePair.Key += 1;
MyKeyValuePair.Value += 1;
или, возможно:
var temp = MyKeyValuePair;
MyKeyValuePair.Key = temp.Key+1;
MyKeyValuePair.Value = temp.Value+1;
ипоследствия потоков были бы гораздо яснее.