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"