Ist es mit der neuen C # 7-Tupelsyntax möglich, ein Lambda mit einem Tupel als Parameter anzugeben und entpackte Werte innerhalb des Lambda zu verwenden?
Beispiel:
var list = new List<(int,int)>();
normale Art, ein Tupel in Lambda zu verwenden:
list.Select(value => value.Item1*2 + value.Item2/2);
Ich erwartete etwas neuen Zucker zu vermeiden .Item1
.Item2
, wie:
list.Select((x,y) => x*2 + y/2);
Die letzte Zeile funktioniert nicht, da sie als zwei Parameter für Lambda behandelt wird. Ich bin mir nicht sicher, ob es tatsächlich einen Weg gibt, dies zu tun.
BEARBEITEN:
Ich habe versucht, doppelte Klammern in der Lambda-Definition zu verwenden, und es hat nicht funktioniert: ((x,y)) => ...
und vielleicht war es dumm, es zu versuchen, aber doppelte Klammern funktionieren hier tatsächlich:
list.Add((1,2));
Außerdem geht es bei meiner Frage nicht ganz darum, hässliche Standardnamen zu vermeiden .Item .Item2
, sondern darum, ein Tupel in Lambda tatsächlich zu entpacken (und vielleicht, warum es nicht implementiert oder nicht möglich ist). Wenn Sie hierher gekommen sind, um eine Lösung für Standardnamen zu finden, lesen Sie die Antwort von Sergey Berezovskiy .
EDIT 2:
Ich dachte nur an einen allgemeineren Anwendungsfall: Ist es möglich (oder warum nicht), ein an eine Methode übergebenes Tupel zu "dekonstruieren"? So was:
void Foo((int,int)(x,y)) { x+y; }
An Stelle von:
void Foo((int x,int y) value) { value.x+value.y }
Enumerable.Select
hat einenFunc<TSource, TResult>
Delegaten als Parameter. Es akzeptiert ein einzelnes Argument vom Typ TSource und Sie können das nicht ändernlist.Select(t => { (int x, int y) = t; return x * 2 + y / 2 });
, aber an diesem Punkt verlieren Sie meiner Meinung nach die Prägnanz der Tupelsyntax gegenüber der obigen Alternative.Dekonstruktionen in C # 7.0 unterstützen drei Formen:
(var x, var y) = e;
),(x, y) = e;
),foreach(var(x, y) in e) ...
).Andere Kontexte wurden berücksichtigt, haben jedoch wahrscheinlich einen abnehmenden Nutzen, und wir konnten sie im Zeitrahmen von C # 7.0 nicht abschließen. Die Dekonstruktion in einer let-Klausel (
let (x, y) = e ...
) und in Lambdas scheint ein guter Kandidat für eine zukünftige Erweiterung zu sein.Letzteres wird unter https://github.com/dotnet/csharplang/issues/258 erörtert
Bringen Sie dort Ihr Feedback und Ihr Interesse zum Ausdruck, da dies den Vorschlägen von Champions helfen wird.
Weitere Details zu dem, was in der C # 7.0-Dekonstruktion enthalten war, finden Sie im Konstruktionsdokument .
quelle
Das Programm, auf das Sie stoßen, ist die Unfähigkeit des Compilers, auf den Typ in diesem Ausdruck zu schließen:
list.Select(((int x, int y) t) => t.x * 2 + t.y / 2);
Aber da
(int, int)
und(int x, int y)
sind der gleiche CLR-Typ (System.ValueType<int, int>
), wenn Sie die Typparameter angeben:list.Select<(int x, int y), int>(t => t.x * 2 + t.y / 2);
Es wird klappen.
quelle