简体   繁体   English

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

[英]Method parameter: Interface VS Generic type

What are the arguments to use one or another of those two method implementations (in Example class)? 使用这两个方法实现中的一个或另一个的参数是什么(在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: If method returns an IInterface or T I would choose the "generic" way to avoid further casting in type T if needed. PS:如果方法返回一个IInterfaceT,我会选择“通用”方法,以避免在需要时在T类型中进一步转换。

Both appears to be same, but really not. 两者似乎都是一样的,但实际上并非如此。

Generic version will not box the ValueType when passed where as non generic version requires "boxing" 传递时,通用版本不会将ValueType包装在非泛型版本需要“装箱”的位置

Here is a small sample program and relevant IL which demonstrates the situation 这是一个小样本程序和相关的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()
   {

   }
}

Below is the relevant part of IL generated 以下是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

Though it is a matter of preference, While MethodGeneric is the one which will perform better in case of "ValueTypes" 虽然这是一个偏好的问题,但MethodGeneric是在“ValueTypes”的情况下表现更好的那个

I suggest passing Interface as a simple parameter, instead of using generic approach, for these reasons: 我建议将Interface作为一个简单的参数传递,而不是使用通用方法,原因如下:

  1. Simpler design, which results in better maintainability 设计更简单,可实现更好的可维护性
  2. More readable code, lesser professional knowledge 更易读的代码,更少的专业知识
  3. Better support for Dependency Injection and IoC 更好地支持依赖注入和IoC
  4. No reflection (I'm not sure about this, I'm going to provide proof, because generics use reflection to understand the type) 没有反思(我不确定这一点,我将提供证据,因为泛型使用反射来理解类型)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM