Я пытаюсь собрать все ситуации, в которых бокс происходит в С#:
-
Преобразование типа значения в
System.Objecttype:struct S { } object box = new S(); -
Преобразование типа значения в
System.ValueTypetype:struct S { } System.ValueType box = new S(); -
Преобразование значения типа перечисления в тип
System.Enum:enum E { A } System.Enum box = E.A; -
Преобразование типа значения в ссылку на интерфейс:
interface I { } struct S : I { } I box = new S(); -
Использование типов значений в конкатенации строк С#:
char c = F(); string s1 = "char value will box" + c;примечание: константы типа
charобъединяются во время компиляциипримечание: с версии 6.0 С# компилятор оптимизирует конкатенацию с использованием
bool,char,IntPtr,UIntPtrтипы -
Создание делегата из метода экземпляра типа значения:
struct S { public void M() {} } Action box = new S().M; -
Вызов непереопределенных виртуальных методов для типов значений:
enum E { A } E.A.GetHashCode(); -
Использование констант С# 7.0 в выражении
is:int x = …; if (x is 42) { … } // boxes both 'x' and '42'! -
Бокс в преобразованиях типов кортежей С#:
(int, byte) _tuple; public (object, object) M() { return _tuple; // 2x boxing } -
Дополнительные параметры типа
objectсо значениями значений по умолчанию:void M([Optional, DefaultParameterValue(42)] object o); M(); // boxing at call-site -
Проверка значения неограниченного общего типа для
null:bool M<T>(T t) => t != null; string M<T>(T t) => t?.ToString(); // ?. checks for null M(42);Примечание: это может быть оптимизировано JIT в некоторых .NET-режимах
-
Тип тестирования для неограниченного или
structобщего типа с операторамиis/as:bool M<T>(T t) => t is int; int? M<T>(T t) => t as int?; IEquatable<T> M<T>(T t) => t as IEquatable<T>; M(42);Примечание: это может быть оптимизировано JIT в некоторых .NET-режимах
Есть ли еще какие-нибудь ситуации в боксе, возможно, скрытые, о которых вы знаете?