C # Schalter in Lambda-Ausdruck
-
07-07-2019 - |
Frage
Ist es möglich, ve einen Schalter in einem Lambda-Ausdruck in ha? Wenn nicht, warum? ReSharper zeigt es als Fehler.
Lösung
Sie können in einem Anweisungsblock lambda:
Action<int> action = x =>
{
switch(x)
{
case 0: Console.WriteLine("0"); break;
default: Console.WriteLine("Not 0"); break;
}
};
Aber man kann es nicht in einem „einzigen Ausdruck Lambda“, so ist dies ungültig:
// This won't work
Expression<Func<int, int>> action = x =>
switch(x)
{
case 0: return 0;
default: return x + 1;
};
Dies bedeutet, dass Sie nicht Schalter in einem Ausdrucksbaum verwenden können (zumindest die durch den C # -Compiler, ich glaube, .NET 4.0 zumindest hat die Unterstützung für sie in den Bibliotheken)
.Andere Tipps
In einem reinen Expression
(in .NET 3.5), die nächstgelegene Sie bekommen können, ist eine Verbindung, bedingt:
Expression<Func<int, string>> func = x =>
x == 1 ? "abc" : (
x == 2 ? "def" : (
x == 3 ? "ghi" :
"jkl")); /// yes, this is ugly as sin...
Nicht Spaß, vor allem, wenn es komplexer wird. Wenn Sie einen Lamda-Ausdruck mit einer Aussage Körper bedeuten (nur für die Verwendung mit LINQ-to-Objects), dann ist alles in den geschweiften Klammern legal:
Func<int, string> func = x => {
switch (x){
case 1: return "abc";
case 2: return "def";
case 3: return "ghi";
default: return "jkl";
}
};
Natürlich könnten Sie in der Lage sein, die Arbeit auszulagern; B. LINQ-to-SQL ermöglicht es Ihnen, eine skalare UDF abzubilden (in der Datenbank) ein Verfahren auf dem Datenkontext (dh nicht tatsächlich verwendet wird) - zum Beispiel:
var qry = from cust in ctx.Customers
select new {cust.Name, CustomerType = ctx.MapType(cust.TypeFlag) };
wo MapType
ist ein UDF, die die Arbeit an der DB-Server der Fall ist.
Ja, es funktioniert, aber Sie haben Ihren Code in einem Block zu setzen. Beispiel:
private bool DoSomething(Func<string, bool> callback)
{
return callback("FOO");
}
Dann rufen sie:
DoSomething(val =>
{
switch (val)
{
case "Foo":
return true;
default:
return false;
}
});
Hmm, sehe ich keinen Grund, warum dies nicht funktionieren sollte. Seien Sie einfach vorsichtig mit der Syntax, die Sie verwenden
param => {
// Nearly any code!
}
delegate (param) {
// Nearly any code!
}
param => JustASingleExpression (No switches)
Ich habe es auch: -)
[Test]
public void SwitchInLambda()
{
TakeALambda(i => {
switch (i)
{
case 2:
return "Smurf";
default:
return "Gnurf";
}
});
}
public void TakeALambda(Func<int, string> func)
{
System.Diagnostics.Debug.WriteLine(func(2));
}
funktioniert gut (Ausgänge "Smurf")!
ich dies nur lernen:
(model) =>
{
switch(model.SentInvoiceTypeId)
{
case 1:
return "1 asdf";
case 2:
return "2 asdf";
case 3:
return "3 asdf ";
case 4:
return "4 asdf ";
default:
return "asdf";
}
}
Gerade zwischen dem „Modell“ () setzen und den Code in {} hinzufügen, denken Sie daran eine Rückkehr zu haben.
Ich bin nicht sicher, in welchen Versionen von C # arbeiten, in diesem Beispiel ist die C # 7.0
Ich hoffe, dass diese Antwort kann jemand helfen.