6

使用这两种方法实现中的一种或另一种的参数是什么(在示例类中)?

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();
    }
}

PS:如果方法返回IInterfaceT我会选择“通用”方式以避免在需要时进一步转换类型T 。

4

2 回答 2

4

两者似乎相同,但实际上并非如此。

通用版本在传递时不会装箱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 会表现得更好

于 2013-11-13T10:09:05.223 回答
3

我建议将 Interface 作为简单参数传递,而不是使用通用方法,原因如下:

  1. 设计更简单,可维护性更好
  2. 更易读的代码,更少的专业知识
  3. 更好地支持依赖注入和 IoC
  4. 没有反射(我不确定这个,我要提供证据,因为泛型使用反射来理解类型)
于 2013-11-13T10:09:19.223 回答