2009-02-27 10 views
8

Czy przejście obiektu do funkcji implementującej konkretny interfejs powoduje, że funkcja akceptuje tylko ten interfejs? Jak:Pytanie interfejsu C#

Change (IEnumerable<T> collection) 

i mijam:

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

których każdy z nich implementuje IEnumerable. Ale kiedy przekażecie którąś z tych metod do zmiany, to czy są oni rzucani do IEnumerable, a zatem istnieje koszt rzutu, ale także kwestia utraty ich unikalnych metod, itp.?

+0

+1 Bardzo interesujące pytanie! –

Odpowiedz

14

Nie, nie jest wymagana obsada od List<T>IS-AIEnumerable<T>. Wykorzystuje to polimorfizm, który nie wymaga odlewania.

Edycja: Oto przykład:

using System; 
using System.Collections.Generic; 

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

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

IL dla Main jest:

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

I jak widać nie ma udział odlewania. Instancja List<T> jest wypychana na stos, a następnie foo jest wywoływana natychmiast po.

+0

Ponadto obiekty nie "tracą" swoich metod, po prostu nie są dostępne wewnątrz funkcji. Jest to ok, ponieważ metoda oczekuje tylko IEnumerable i dlatego powinna używać tylko metod dostępnych przez ten interfejs. – tvanfosson

0

Nie sądzę, że jest to koszt. Ponieważ typy już implementują IEnumerable, obiekt powinien być w stanie być użyty od razu (zauważ, że to głównie domysły, nie mam pojęcia o tym, jak vtables CLR naprawdę działają za kulisami).

Jeśli jest to koszt, będzie on tak niesamowicie mały, że jeśli ma znaczenie, prawdopodobnie nie powinieneś używać CLR na początku.