2009-04-27 4 views

Antwort

3

Der Unterschied besteht darin, dass das erste man in etwas passieren würde es ermöglichen, die eine konkretere Art IFileInfo Umsetzung verwendet. Zum Beispiel:

Func<IEnumerable<SpecialFileInfo>> lister =() => ListFiles(); 
Import(lister, file => Console.WriteLine(file.SpecialProperty)); 

(. Wo SpecialProperty eine Eigenschaft ist, die auf SpecialFileInfo existiert, aber nicht IFileInfo) Sie können dies nicht tun, mit dieser Form.

Es gibt eine sehr geringe Ausführungszeit Strafe für generische Methoden und Typen - es wird JITted einmal für jeden Werttyp T Typ Argument (nicht vergessen, ein Wert Typ könnte implementieren IFileInfo) und einmal für alle Referenztyp (dh sobald es JITted oder ein Referenztyp ist, muss es nicht erneut JITted werden). Dies wird jedoch in Ihrer realen Anwendung sicherlich vernachlässigbar sein.

+0

Danke, Jon. Ich war mir der Ausführungsverzögerung nicht bewusst, die durch generische Methoden/Typen verursacht wurde. Ich bezweifle, dass dies zu erheblichen Leistungseinbußen in meiner Bewerbung führen würde. – Sung

+0

In der Tat, es ist fast immer vernachlässigbar - und es ist nur höchstens einmal pro Typ Argument, droht, wenn Sie Foo verwenden und später wieder Foo verwenden, wird es den Code JITted früher verwenden. –

1

Es gibt keine Laufzeitleistungseinbußen - dies wird vom Compiler beim Generieren von IL für Ihren Code erledigt.

Wie für die Syntax, ich denke, die zweite macht es klarer, dass Sie nur an der IFileInfo-Schnittstelle interessiert sind.

1

In diesem Fall gibt es nicht viel Unterschied, aber sagen Sie, dass Sie es weiter begrenzen möchten, zum Beispiel möchten Sie, dass T einen parameterlosen Standardkonstruktor hat. Sie können es die erste Möglichkeit, nur tun:

public void Import<T>(
     Func<IEnumerable<T>> getFiles, Action<T> import) 
      where T : IFileInfo, new() 
    { 
      // Import files retrieved through "getFiles" 
    } 
+0

+1 für etwas, das ich nicht berücksichtigt habe. – Sung

1

Sie werden keinen Unterschied auf der Funktionsseite bemerken, aber Sie können eine auf der Anruferseite sehen.

public class MyFileInfo : IFileInfo 
{ 
    public string MyString { get; set; } 
} 

Import<MyFileInfo>(files, 
        (mfi) => Console.WriteLine("Import {0}", mfi.MyString)); 
2

Obwohl diese Fragen bereits beantwortet: Vielleicht mit weniger restriktiven Lösung gehen wollen Sie:

public void Import<T,S>(
     Func<IEnumerable<S>> getFiles, Action<T> import) 
      where T : IFileInfo 
      where S : T 
    { 
      // Import files retrieved through "getFiles" 
    } 

Dies ermöglicht ein Action<IFileInfo> und ein Func<IEnumerable<ConcreteFileInfo>> weitergegeben werden.

+0

Das ist großartig. – Sung

Verwandte Themen