将对象传递给实现特定接口的函数是否有成本,函数只接受该接口?像:
Change (IEnumerable<T> collection)
我通过了:
List<T>
LinkedList<T>
CustomCollection<T>
所有这些都实现了IEnumerable。但是当你将其中的任何一个传递给Change方法时,它们是否会被转换为IEnumerable,因此存在一个演员阵容以及丢失其独特方法等问题?
答案 0 :(得分: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) { }
}
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
。
答案 1 :(得分:0)
我不相信会有成本。由于类型已经实现了IEnumerable,因此该对象应该能够立即使用(请注意,这主要是猜测;我不知道CLR的vtable如何在幕后工作)。
如果有成本,它会非常小,如果它有所作为,你可能不应该开始使用CLR。