views:

347

answers:

3

Is there a cost in passing an object to a function that implements a particular interface where the function only accepts that interface? Like:

Change (IEnumerable<T> collection)

and I pass:

List<T>
LinkedList<T>
CustomCollection<T>

which all of them implements IEnumerable. But when you pass any of those to the Change method, are they cast to IEnumerable, thus there is a cast cost but also the issue of losing their unique methods, etc?

+15  A: 

No, there is no cast involved since List<T> IS-A IEnumerable<T>. This is using polymorphism which does not require casting.

Edit: Here is an example:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
     foo(new List<int>());
    }

    static void foo(IEnumerable<int> list) { }
}

The IL for Main is:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: nop 
    L_0001: newobj instance void [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
    L_0006: call void Program::foo(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>)
    L_000b: nop 
    L_000c: ret 
}

And as you can see there is no casting involved. The instance of List<T> is pushed onto the stack and them foo is called immediately after.

Andrew Hare
Plus the object's don't "lose" their methods, they are just not available inside the function. This is ok because the method only expect IEnumerable<T> and should thus only use the methods available via that interface.
tvanfosson
A: 

The cost of the implicit change of type* (I don't think it's actually a cast) would be less than the mere cost of just calling the method, I wager.

Other than that, I'm not sure what your question is.

*The type of the object isn't actually changing, just the type of your local reference. You could still cast the object back to its original type in the function, if you knew what that was.

mquander
A: 

I don't believe there's a cost. Since the types already implement IEnumerable, the object should be able to be used straight away (note that this is mostly a guess; I have no idea about how the CLR's vtables really work behind the scenes).

If there is a cost, it will be so amazingly small that, if it makes a difference, you probably shouldn't be using the CLR to begin with.

overslacked