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