Ich dachte, es wäre schön, so etwas zu tun (wobei das Lambda eine Rendite erzielt):
public IList<T> Find<T>(Expression<Func<T, bool>> expression) where T : class, new()
{
IList<T> list = GetList<T>();
var fun = expression.Compile();
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item; // This is not allowed by C#
}
return items.ToList();
}
Ich habe jedoch festgestellt, dass ich Yield nicht in anonymen Methoden verwenden kann. Ich frage mich warum. Die Ertragsdokumente sagen nur, dass es nicht erlaubt ist.
Da es nicht erlaubt war, habe ich einfach eine Liste erstellt und die Elemente hinzugefügt.
c#
yield
anonymous-methods
yield-return
Lance Fisher
quelle
quelle
async
Lambdas zulassen könnenawait
, würde mich interessieren, warum sie noch keine anonymen Iteratoren mityield
Inside implementiert haben . Mehr oder weniger ist es der gleiche Generator für Zustandsmaschinen.Antworten:
Eric Lippert hat kürzlich eine Reihe von Blog-Posts darüber geschrieben, warum Erträge in einigen Fällen nicht zulässig sind.
EDIT2:
Dort finden Sie wahrscheinlich die Antwort ...
EDIT1: Dies wird in den Kommentaren von Teil 5 in Erics Antwort auf Abhijeet Patels Kommentar erklärt:
F:
EIN :
quelle
Eric Lippert hat eine hervorragende Artikelserie über die Einschränkungen (und Entwurfsentscheidungen, die diese Auswahl beeinflussen) für Iteratorblöcke geschrieben
Insbesondere Iteratorblöcke werden durch einige ausgefeilte Compiler-Code-Transformationen implementiert. Diese Transformationen würden sich auf die Transformationen auswirken, die in anonymen Funktionen oder Lambdas stattfinden, so dass beide unter bestimmten Umständen versuchen würden, den Code in ein anderes Konstrukt zu "konvertieren", das mit dem anderen nicht kompatibel ist.
Infolgedessen ist ihnen die Interaktion verboten.
Wie Iteratorblöcke unter der Haube funktionieren, wird hier gut behandelt .
Als einfaches Beispiel für eine Inkompatibilität:
Der Compiler möchte dies gleichzeitig in Folgendes konvertieren:
Gleichzeitig versucht der Iterator-Aspekt, eine kleine Zustandsmaschine zu erstellen. Bestimmte einfache Beispiele funktionieren möglicherweise mit einer angemessenen Überprüfung der Integrität (zuerst mit den (möglicherweise willkürlich) verschachtelten Abschlüssen) und dann, ob die resultierenden Klassen der untersten Ebene in Iterator-Zustandsmaschinen umgewandelt werden können.
Dies wäre jedoch
In Ihrem Beispiel so:
quelle
Magic
Klasse seinMagic<T>
.Leider weiß ich nicht, warum sie das nicht zugelassen haben, da es natürlich durchaus möglich ist, sich vorzustellen, wie das funktionieren würde.
Anonyme Methoden sind jedoch bereits ein Stück "Compiler-Magie" in dem Sinne, dass die Methode entweder in eine Methode in der vorhandenen Klasse oder sogar in eine ganz neue Klasse extrahiert wird, je nachdem, ob es sich um lokale Variablen handelt oder nicht.
Darüber hinaus werden Iterator-Methoden
yield
mit Compiler Magic implementiert.Ich vermute, dass einer dieser beiden Codes den Code für das andere Stück Magie nicht identifizierbar macht und dass beschlossen wurde, keine Zeit darauf zu verwenden, dass dies für die aktuellen Versionen des C # -Compilers funktioniert. Natürlich ist es möglicherweise überhaupt keine bewusste Entscheidung, und dass es einfach nicht funktioniert, weil niemand daran gedacht hat, es umzusetzen.
Für eine 100% genaue Frage würde ich vorschlagen, dass Sie die Microsoft Connect- Website verwenden und eine Frage melden. Ich bin sicher, dass Sie im Gegenzug etwas Verwendbares erhalten.
quelle
Ich würde das tun:
Natürlich benötigen Sie die System.Core.dll, auf die in .NET 3.5 verwiesen wird, für die Linq-Methode. Und umfassen:
Prost,
Schlau
quelle
Vielleicht ist es nur eine Syntaxbeschränkung. In Visual Basic .NET, das C # sehr ähnlich ist, ist das Schreiben durchaus möglich, obwohl es umständlich ist
Beachten Sie auch die Klammern
' here
; die Lambda - FunktionIterator Function
...End Function
gibt einIEnumerable(Of Integer)
aber ist nicht ein solches Objekt selbst. Es muss aufgerufen werden, um dieses Objekt zu erhalten.Der konvertierte Code von [1] löst Fehler in C # 7.3 (CS0149) aus:
Ich stimme dem in den anderen Antworten angegebenen Grund nicht zu, dass es für den Compiler schwierig ist, damit umzugehen. Das
Iterator Function()
im VB.NET-Beispiel angezeigte Beispiel wurde speziell für Lambda-Iteratoren erstellt.In VB gibt es das
Iterator
Schlüsselwort; es hat kein C # Gegenstück. IMHO gibt es keinen wirklichen Grund, warum dies kein Merkmal von C # ist.Wenn Sie also wirklich, wirklich anonyme Iteratorfunktionen möchten, verwenden Sie derzeit Visual Basic oder (ich habe es nicht überprüft) F #, wie in einem Kommentar von Teil # 7 in der Antwort von @Thomas Levesque angegeben (drücken Sie Strg + F für F #).
quelle