2010-09-18 3 views
8

Как я понимаю, C# /. Net generics поддерживают некоторую степень reification. Так что, если у меня есть следующий код:Как генерические средства C# влияют на коллекции с примитивами

List<int> list = new List<int>(); 
list.Add(1); 

Будет ли значение 1 будет autoboxed или будет обрабатывать примитивный Интс «список» объект эффективно?

ответ

18

Нет, это не будет в штучной упаковке. Во время выполнения базовый массив для List<int> будет действительно int[]. Обратите внимание, что это не только случай с подлинными примитивными типами: List<T> не будет содержать значения любого типа значений (при условии, что он был объявлен как List<Guid> и т. Д., А не List<object>).

В общем случае, генерические файлы в .NET хранят намного больше информации, чем в Java. CLR изначально понимает дженерики и имеет дело с ними надлежащим образом, а не на Java, где JVM в значительной степени не знает их.

Например, если вы пишете:

object list = new List<string>(); 
Type type = list.GetType(); 

Тогда type будет равна - который затем отличается (скажем) List<Guid> и т.д.

3

.NET generics становятся специализированными для структур, поэтому в вашем случае нет бокса. Обратите внимание, что в любом случае нет необходимости в кастинге.

5

В int значения не будут боксировал в пределах список. Это одна из красавиц с дженериками, что компилятор (точнее, JIT-компилятор, я полагаю) построит типизированную версию класса List<>, вместо того, чтобы хранить значения как object. Таким образом, он не только обеспечивает безопасность типов посредством открытых методов и свойств, но и на самом деле набирается во всех аспектах.

5

Как уже отмечалось, джиттер генерирует новый код для каждой конструкции, включающей новый тип значения. Интересный момент, который еще не упоминался до сих пор, заключается в том, что джиттер будет генерировать код один раз для построения ссылочного типа и повторного использования, что для каждый ссылочный тип. Код для List<object> точно такой же, как код для List<string>.

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

+0

Однако вызов, например, 'new T [10]' будет по-прежнему создавать правильный тип массива, даже для ссылочных типов. –

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