2009-02-27 11 views
8

C'è un costo nel passare un oggetto a una funzione che implementa una particolare interfaccia in cui la funzione accetta solo quell'interfaccia? Come:Interfaccia C# domanda

Change (IEnumerable<T> collection) 

e passo:

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

che tutti loro implementa IEnumerable. Ma quando passi a qualcuno di questi nel metodo Change, vengono inseriti in IEnumerable, quindi c'è un costo di cast ma anche il problema di perdere i loro metodi univoci, etc?

+0

+1 Domanda molto interessante! –

risposta

14

No, non è presente il cast dal List<T>IS-AIEnumerable<T>. Questo sta usando il polimorfismo che non richiede il casting.

Edit: Ecco un esempio:

using System; 
using System.Collections.Generic; 

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

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

La IL per 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 
} 

E come si può vedere non c'è fusione coinvolti. L'istanza di List<T> viene inserita nello stack e vengono richiamati immediatamente dopo foo.

+0

Inoltre gli oggetti non "perdono" i loro metodi, sono semplicemente non disponibili all'interno della funzione. Questo va bene perché il metodo si aspetta solo IEnumerable e dovrebbe quindi utilizzare solo i metodi disponibili tramite tale interfaccia. – tvanfosson

0

Non credo ci sia un costo. Dal momento che i tipi implementano già IEnumerable, l'oggetto dovrebbe essere immediatamente utilizzabile (si noti che questo è per lo più un'ipotesi, non ho idea di come i vtable del CLR funzionino davvero dietro le quinte).

Se c'è un costo, sarà così incredibilmente piccolo che, se fa la differenza, probabilmente non dovresti usare il CLR per cominciare.