Ich schaue mir die neuen Implementierungen in C # 7.0 an und finde es interessant, dass sie lokale Funktionen implementiert haben, aber ich kann mir kein Szenario vorstellen, in dem eine lokale Funktion einem Lambda-Ausdruck vorgezogen würde und was der Unterschied zwischen beiden ist.
Ich verstehe, dass Lambdas anonymous
Funktionen sind, während lokale Funktionen dies nicht sind, aber ich kann mir kein reales Szenario vorstellen, in dem lokale Funktionen Vorteile gegenüber Lambda-Ausdrücken haben
Jedes Beispiel wäre sehr dankbar. Vielen Dank.
Antworten:
Dies wurde von Mads Torgersen in C # Design Meeting Notes erklärt, in denen lokale Funktionen zuerst besprochen wurden :
Um es noch weiter zu erweitern, sind die Vorteile:
Performance.
Beim Erstellen eines Lambda muss ein Delegat erstellt werden, was in diesem Fall eine unnötige Zuordnung darstellt. Lokale Funktionen sind eigentlich nur Funktionen, es sind keine Delegierten erforderlich.
Außerdem sind lokale Funktionen beim Erfassen lokaler Variablen effizienter: Lambdas erfassen normalerweise Variablen in einer Klasse, während lokale Funktionen eine Struktur (übergeben mit
ref
) verwenden können, wodurch wiederum eine Zuordnung vermieden wird.Dies bedeutet auch, dass das Aufrufen lokaler Funktionen billiger ist und eingebunden werden kann, wodurch die Leistung möglicherweise noch weiter gesteigert wird.
Lokale Funktionen können rekursiv sein.
Lambdas können auch rekursiv sein, erfordern jedoch umständlichen Code, bei dem Sie zuerst
null
einer Delegatenvariablen und dann dem Lambda zuweisen . Lokale Funktionen können natürlich rekursiv sein (einschließlich gegenseitig rekursiv).Lokale Funktionen können generisch sein.
Lambdas können nicht generisch sein, da sie einer Variablen mit einem konkreten Typ zugewiesen werden müssen (dieser Typ kann generische Variablen aus dem äußeren Bereich verwenden, aber das ist nicht dasselbe).
Lokale Funktionen können als Iterator implementiert werden.
Lambdas kann das Schlüsselwort
yield return
(undyield break
) nicht verwenden , um dieIEnumerable<T>
Rückgabefunktion zu implementieren . Lokale Funktionen können.Lokale Funktionen sehen besser aus.
Dies wird im obigen Zitat nicht erwähnt und ist möglicherweise nur meine persönliche Neigung, aber ich denke, dass die normale Funktionssyntax besser aussieht, als einer Delegatenvariablen ein Lambda zuzuweisen. Lokale Funktionen sind auch prägnanter.
Vergleichen Sie:
quelle
Func<int, int, int> f = (x, y) => x + y; f(arg1:1, arg2:1);
.object
. Lambdas könnten also eine Struktur verwenden, aber sie müsste eingerahmt werden, damit Sie immer noch diese zusätzliche Zuordnung haben.Neben der großartigen Antwort von svick bieten lokale Funktionen noch einen weiteren Vorteil:
Sie können überall in der Funktion definiert werden, auch nach der
return
Anweisung.quelle
#region Helpers
gewöhnen kann, alle Hilfsfunktionen am unteren Rand der Funktion zu platzieren, um Unordnung innerhalb dieser Funktion und insbesondere Unordnung in der Hauptklasse zu vermeiden.Wenn Sie sich auch fragen, wie Sie die lokale Funktion testen können, sollten Sie JustMock überprüfen, da es über die entsprechenden Funktionen verfügt. Hier ist ein einfaches Klassenbeispiel, das getestet wird:
Und so sieht der Test aus:
Hier ist ein Link zur JustMock- Dokumentation .
Haftungsausschluss. Ich bin einer der Entwickler, die für JustMock verantwortlich sind .
quelle
.DoNothing().OccursOnce();
Und behaupten Sie später, dass der Aufruf durch Aufrufen derMock.Assert(foo);
Methode erfolgt ist. Wenn Sie interessiert sind, wie andere Szenarien unterstützt werden, lesen Sie unseren Hilfeartikel Asserting Occurrence .Ich verwende Inline-Funktionen, um den Druck der Speicherbereinigung zu vermeiden, insbesondere wenn es um länger laufende Methoden geht. Angenommen, man möchte 2 Jahre oder Marktdaten für ein bestimmtes Tickersymbol erhalten. Außerdem kann man bei Bedarf eine Menge Funktionalität und Geschäftslogik packen.
Sie öffnen eine Socket-Verbindung zum Server und durchlaufen die Daten, die ein Ereignis an ein Ereignis binden. Man kann es sich genauso vorstellen, wie eine Klasse entworfen wurde, nur schreibt man nicht überall Hilfsmethoden, die wirklich nur für ein Stück Funktionalität funktionieren. Im Folgenden finden Sie ein Beispiel dafür, wie dies aussehen könnte. Bitte beachten Sie, dass ich Variablen verwende und die "Helfer" -Methoden unter dem Endlich stehen. Im Schließlich entferne ich die Ereignishandler, wenn meine Exchange-Klasse extern / injiziert wäre, hätte ich keinen ausstehenden Ereignishandler registriert
Sie können die Vorteile wie unten erwähnt sehen, hier sehen Sie eine Beispielimplementierung. Hoffe, das hilft, die Vorteile zu erklären.
quelle