Рассмотрим:
int a = 42;
// Reference equality on two boxed ints with the same value
Console.WriteLine( (object)a == (object)a ); // False
// Same thing - listed only for clarity
Console.WriteLine(ReferenceEquals(a, a)); // False
Очевидно, что каждая инструкция по боксу выделяет отдельный экземпляр Int32
в штучной упаковке, поэтому равенство между ними не выполняется. Эта страница появляется, чтобы указать, что это заданное поведение:
Инструкция box преобразует 'raw'
(unboxed) тип значения в объект
ссылка (тип O). Это
завершено созданием нового объекта
и копирование данных из значения
введите во вновь выделенный объект.
Но почему это так?
Есть ли убедительная причина, по которой CLR не решает хранить «кэш» в штучной упаковке Int32
с или даже более сильные общие значения для всех примитивных типов значений (которые все являются неизменяемыми)? Я знаю, что у Java есть что-то вроде этого.
В дни отсутствия универсальных систем, не сильно ли это помогло бы снизить требования к памяти и рабочую нагрузку GC для большого ArrayList
, состоящего в основном из маленьких целых чисел? Я также уверен, что существует несколько современных .NET-приложений, которые делают , использующие универсальные шаблоны, но по какой-либо причине (рефлексия, назначения интерфейса и т. Д.) Запускают большие бокс-выделения, которые может быть значительно сокращено с помощью (что представляется ) простой оптимизацией.
Так в чем причина? Некоторое влияние на производительность я не учел (сомневаюсь, что проверка того, что элемент находится в кеше и т. Д., Приведет к чистой потере производительности, но что я знаю)? Сложности реализации? Проблемы с небезопасным кодом? Нарушение обратной совместимости (я не могу вспомнить ни одной хорошей причины, по которой хорошо написанная программа должна полагаться на существующее поведение)? Или что-то другое?
РЕДАКТИРОВАТЬ : Я действительно предлагал статический кэш "часто встречающихся" примитивов , очень похожий на то, что делает Java . Пример реализации см. В ответе Джона Скита. Я понимаю, что делать это для произвольных, возможно изменяемых, типов значений или динамически «запоминания» экземпляров во время выполнения - это совершенно другой вопрос.
РЕДАКТИРОВАТЬ : изменен заголовок для ясности.