C#在lambda表达式中切换
是否有可能在lambda表达式中进行切换? 如果没有,为什么? Resharper将其显示为错误。
你可以在一个语句块lambda:
Action action = x => { switch(x) { case 0: Console.WriteLine("0"); break; default: Console.WriteLine("Not 0"); break; } };
但你不能在“单表达式lambda”中这样做,所以这是无效的:
// This won't work Expression> action = x => switch(x) { case 0: return 0; default: return x + 1; };
这意味着你不能在表达式树中使用switch(至少由C#编译器生成;我相信.NET 4.0至少在库中支持它)。
在纯Expression
(在.NET 3.5中)中,您可以获得的最接近的是复合条件:
Expression> func = x => x == 1 ? "abc" : ( x == 2 ? "def" : ( x == 3 ? "ghi" : "jkl")); /// yes, this is ugly as sin...
没有乐趣,特别是当它变得复杂时。 如果你的意思是带有语句体的lamda表达式(仅用于LINQ-to-Objects),那么大括号内的任何内容都是合法的:
Func func = x => { switch (x){ case 1: return "abc"; case 2: return "def"; case 3: return "ghi"; default: return "jkl"; } };
当然,你可以将工作外包出去; 例如,LINQ-to-SQL允许您将标量UDF(在数据库中)映射到数据上下文中的方法(实际上未使用) – 例如:
var qry = from cust in ctx.Customers select new {cust.Name, CustomerType = ctx.MapType(cust.TypeFlag) };
其中MapType
是在db服务器上执行工作的UDF。
是的,它可以工作,但你必须把你的代码放在一个块里。 例:
private bool DoSomething(Func callback) { return callback("FOO"); }
然后,打电话给它:
DoSomething(val => { switch (val) { case "Foo": return true; default: return false; } });
嗯,我认为没有理由不这样做。 请注意您使用的语法
param => { // Nearly any code! } delegate (param) { // Nearly any code! } param => JustASingleExpression (No switches)
我也查了一下:-)
[Test] public void SwitchInLambda() { TakeALambda(i => { switch (i) { case 2: return "Smurf"; default: return "Gnurf"; } }); } public void TakeALambda(Func func) { System.Diagnostics.Debug.WriteLine(func(2)); }
工作得很好(输出“Smurf”)!