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”)!