2009-02-27 72 views
8

将对象传递给实现特定接口的函数是否有成本,而函数只接受该接口?像:C#接口问题

Change (IEnumerable<T> collection) 

和我通:

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

使所有这些实现IEnumerable。但是当你将其中的任何一个传递给Change方法时,它们是否会转换为IEnumerable,因此存在投射成本,但也会失去其独特方法等问题?

+0

+1非常有趣的问题! – 2009-02-27 17:32:45

回答

14

不,没有铸造涉及List<T>IS-AIEnumerable<T>。这是使用不需要投射的多态性。

编辑:下面是一个例子:

using System; 
using System.Collections.Generic; 

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

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

Main的IL是:

.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 
} 

正如你可以看到有没有参与铸造。将List<T>的实例推入堆栈,并在之后立即调用foo

+0

加上对象不会“丢失”他们的方法,它们只是在函数内部不可用。这是可以的,因为该方法仅期望IEnumerable ,因此应该只使用通过该接口可用的方法。 – tvanfosson 2009-02-27 17:31:39

0

我不相信会有成本。由于这些类型已经实现了IEnumerable,因此该对象应该可以立即使用(请注意,这主要是一种猜测;我不知道CLR的vtables是如何在幕后真正起作用的)。

如果是有成本的,这将是令人惊讶这么小,如果它的确与众不同,你可能不应该使用CLR开始。