Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method parameter: Interface VS Generic type

Tags:

c#

generics

What are the arguments to use one or another of those two method implementations (in Example class)?

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.

like image 269
Askolein Avatar asked Nov 13 '13 09:11

Askolein


People also ask

What is a parameterized or generic type?

A parameterized type is an instantiation of a generic type with actual type arguments. A generic type is a reference type that has one or more type parameters. These type parameters are later replaced by type arguments when the generic type is instantiated (or declared ).

Can a generic type be an interface?

Java Generic Classes and Subtyping We can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.

When would you use a generic interface?

It's often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. To avoid boxing and unboxing operations on value types, it's better to use generic interfaces, such as IComparable<T>, on generic classes.

Can we have generic interface in C#?

You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.


2 Answers

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"

like image 170
Sriram Sakthivel Avatar answered Oct 16 '22 09:10

Sriram Sakthivel


I suggest passing Interface as a simple parameter, instead of using generic approach, for these reasons:

  1. Simpler design, which results in better maintainability
  2. More readable code, lesser professional knowledge
  3. Better support for Dependency Injection and IoC
  4. No reflection (I'm not sure about this, I'm going to provide proof, because generics use reflection to understand the type)
like image 24
Saeed Neamati Avatar answered Oct 16 '22 08:10

Saeed Neamati