Я пытаюсь собрать все ситуации, в которых происходит бокс на C #:
Преобразование типа значения в
System.Object
тип:struct S { } object box = new S();
Преобразование типа значения в
System.ValueType
тип: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();
Использование типов значений в конкатенации строк C #:
char c = F(); string s1 = "char value will box" + c;
примечание: константы
char
типа объединяются во время компиляциипримечание: начиная с версии 6.0 C # компилятор оптимизирует конкатенация с участием
bool
,char
,IntPtr
,UIntPtr
типыСоздание делегата из метода экземпляра типа значения:
struct S { public void M() {} } Action box = new S().M;
Вызов непереопределенных виртуальных методов для типов значений:
enum E { A } E.A.GetHashCode();
Использование шаблонов констант C # 7.0 в
is
выражении:int x = …; if (x is 42) { … } // boxes both 'x' and '42'!
Бокс в преобразованиях типов кортежей C #:
(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
Есть ли еще какие-нибудь боксерские ситуации, может быть, скрытые, о которых вы знаете?