8

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

Change (IEnumerable<T> collection)

我通过了:

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

它们都实现了 IEnumerable。但是,当您将其中任何一个传递给 Change 方法时,它们是否会转换为 IEnumerable,因此存在转换成本以及丢失其独特方法等问题?

4

2 回答 2

14

不,自从List<T> IS-A IEnumerable<T>. 这是使用不需要强制转换的多态性。

编辑:这是一个例子:

using System;
using System.Collections.Generic;

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

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

IL 为Main

.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立即调用它们。

于 2009-02-27T17:27:57.123 回答
0

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

如果有成本,它会非常小,如果它有所作为,你可能不应该从一开始就使用 CLR。

于 2009-02-27T17:30:05.403 回答