You can avoid boxing if you change the definition of Method to:
void Method<T>(T i) where T : I { }
This avoids boxing, since at runtime the CLR specializes in generic methods based on the type of generic arguments. Link types can use the same implementation, while structure types get their own version. This means that all operations in Method that depend on T will take into account the size of a particular type of structure.
However, you should be careful, since invoking virtual methods defined in System.Object , for example Equals or GetHashCode , will cause i be boxed, since a method table pointer is required to send the virtual method (although JIT may be able to to send statics in some cases). However, if your type of structure overrides the virtual method (s) in question, then boxing will not need to be done, since the invocation method is again known statically, since the structures (and therefore their members) are sealed.
You can usually avoid directly calling Equals or GetHashCode by restricting T to implement IEquatable<T> and using IEqualityComparer<T> for comparison, for example.
void Method<T>(T i) where T : I, IEquatable<T> { T other = ... if(i.Equals(other))
source share