I'm trying to collect all of the situations in which boxing occurs in C#:
Converting value type to
System.Objecttype:struct S { } object box = new S();Converting value type to
System.ValueTypetype:struct S { } System.ValueType box = new S();Converting value of enumeration type to
System.Enumtype:enum E { A } System.Enum box = E.A;Converting value type into interface reference:
interface I { } struct S : I { } I box = new S();Using value types in C# string concatenation:
char c = F(); string s1 = "char value will box" + c;note: constants of
chartype are concatenated at compile timenote: since version 6.0 C# compiler optimizes concatenation involving
bool,char,IntPtr,UIntPtrtypesCreating delegate from value type instance method:
struct S { public void M() {} } Action box = new S().M;Calling non-overridden virtual methods on value types:
enum E { A } E.A.GetHashCode();Using C# 7.0 constant patterns under
isexpression:int x = …; if (x is 42) { … } // boxes both 'x' and '42'!Boxing in C# tuple types conversions:
(int, byte) _tuple; public (object, object) M() { return _tuple; // 2x boxing }Optional parameters of
objecttype with value type default values:void M([Optional, DefaultParameterValue(42)] object o); M(); // boxing at call-siteChecking value of unconstrained generic type for
null:bool M<T>(T t) => t != null; string M<T>(T t) => t?.ToString(); // ?. checks for null M(42);note: this may be optimized by JIT in some .NET runtimes
Type testing value of unconstrained or
structgeneric type withis/asoperators: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);note: this may be optimized by JIT in some .NET runtimes
Are there any more situations of boxing, maybe hidden, that you know of?