Both appears to be same, but really not.
Generic version will not box the ValueType when passed where as non generic version requires "boxing"
Here is a small sample program and relevant IL which demonstrates the situation
void Main() { Example ex = new Example(); TestStruct tex = new TestStruct(); ex.MethodGeneric(tex); ex.MethodInterface(tex); } public interface IInterface { void DoIt(); } public class Example { public void MethodInterface(IInterface arg) { arg.DoIt(); } public void MethodGeneric<T>(T arg) where T : IInterface { arg.DoIt(); } } internal struct TestStruct : IInterface { public void DoIt() { } }
Below is the relevant part of IL generated
IL_0001: newobj UserQuery+Example..ctor IL_0006: stloc.0 // ex IL_0007: ldloca.s 01 // tex IL_0009: initobj UserQuery.TestStruct IL_000F: ldloc.0 // ex IL_0010: ldloc.1 // tex IL_0011: callvirt UserQuery+Example.MethodGeneric IL_0016: nop IL_0017: ldloc.0 // ex IL_0018: ldloc.1 // tex IL_0019: box UserQuery.TestStruct //<--Box opcode IL_001E: callvirt UserQuery+Example.MethodInterface
Though it is a matter of preference, While MethodGeneric is the one which will perform better in case of "ValueTypes"