两者似乎相同,但实际上并非如此。
通用版本在传递时不会装箱ValueType
,因为非通用版本需要“装箱”
这是一个小示例程序和相关的 IL 演示了这种情况
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()
{
}
}
下面是生成的IL的相关部分
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
虽然这是一个偏好问题,但MethodGeneric
在“ValueTypes”的情况下,While 会表现得更好