6

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.

3
  • 1
    I didn't understand your question. Are you asking about which practice is better? Commented Nov 13, 2013 at 10:01
  • 1
    I don’t think it makes a real difference in this case, but I would argue that using generics here is unnecessarily complicating the situation and likely adds an overhead to the function definition.
    – poke
    Commented Nov 13, 2013 at 10:02
  • @Saeed Neamati: yes best practice but most of all, impacts on design, compilation, further issue we may encounter with one or the other way or maybe one of those solutions is terribly wrong for some reason I am not able to spot.
    – Askolein
    Commented Nov 13, 2013 at 10:05

2 Answers 2

4

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"

3

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)
1
  • 1
    The interface is used in either case so this answer is ambiguous. Commented Nov 13, 2013 at 10:13

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.