方法参数:接口VS通用类型

时间:2013-11-13 09:58:50

标签: c# generics

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

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:如果方法返回 IInterface T ,我会选择“通用”方式,以避免在需要时进一步转换 T 类型

2 个答案:

答案 0 :(得分: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”情况下表现更好的{/ p>}

答案 1 :(得分:3)

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

  1. 设计更简单,可提供更好的可维护性
  2. 更易读的代码,更少的专业知识
  3. 更好地支持依赖注入和IoC
  4. 没有反思(我不确定这一点,我将提供证据,因为泛型使用反射来理解类型)