Оператор `is` применяет `boxing` и `Unboxing` со значимыми типами
Однако, когда оператор `is` используется с ссылочными типами, boxing не происходит, поскольку ссылочные типы уже являются объектами.
Код с оператором `Is`
```csharp
//key имеет тип TKey
//EntityId является значимым типом
if (key is EntityId entityIdKey) {
}
```
Тот же код через IL-viewer
```cil
IL_0001: ldarg.2 // key
IL_0002: box !!0/*TKey*/
IL_0007: isinst AluEngineCore.AluEngine.ECS.Entities.EntityId
IL_000c: brfalse.s IL_0022
IL_000e: ldarg.2 // key
IL_000f: box !!0/*TKey*/
IL_0014: isinst AluEngineCore.AluEngine.ECS.Entities.EntityId
IL_0019: unbox.any AluEngineCore.AluEngine.ECS.Entities.EntityId
IL_001e: stloc.0 // entityIdKey
IL_001f: ldc.i4.1
IL_0020: br.s IL_0023
IL_0022: ldc.i4.0
IL_0023: stloc.2 // V_2
```
Можно увидеть слова `box` и `unbox`, что подтверждает тезис выше.
В приведённом примере IL-кода происходит и boxing, и unboxing в процессе проверки типа с использованием оператора `is`.
1. **Boxing** происходит при приведении дженерик переменной `key` к типу `object` (что необходимо для выполнения операции `is` с типом `EntityId`, который является структурой). Это видно по инструкции `box`.
2. **Unboxing** происходит после того, как проверка типа подтвердила, что объект действительно является экземпляром `EntityId`. Для присвоения этого значения переменной типа `EntityId` производится операция `unbox.any`, которая извлекает значение типа значений из упакованного объекта обратно в структуру `EntityId`.
Этот процесс подтверждается следующими строками IL-кода:
- `box !!0/*TKey*/` — boxing дженерик переменной `key`.
- `isinst AluEngineCore.AluEngine.ECS.Entities.EntityId` — проверка, может ли упакованный объект быть приведён к типу `EntityId`.
- `unbox.any AluEngineCore.AluEngine.ECS.Entities.EntityId` — unboxing объекта обратно в структуру `EntityId` после успешной проверки.