Mic*_*eyn 5 .net c# linq visual-studio-2010 c#-4.0
假设您有以下代码:
string encoded="9,8,5,4,9";
// Parse the encoded string into a collection of numbers
var nums=from string s in encoded.Split(',')
select int.Parse(s);
Run Code Online (Sandbox Code Playgroud)
这很简单,但是如果我想在select中将一个lambda表达式应用于s,但仍然将其保留为声明性查询表达式,换句话说:
string encoded="9,8,5,4,9";
// Parse the encoded string into a collection of numbers
var nums=from string s in encoded.Split(',')
select (s => {/* do something more complex with s and return an int */});
Run Code Online (Sandbox Code Playgroud)
这当然不能编译.但是,如何在不将其转换为流利语法的情况下获得lambda.
更新:感谢StriplingWarrior的指导,我有一个令人费解但可编译的解决方案:
var result=from string s in test.Split(',')
select ((Func<int>)
(() => {string u="1"+s+"2"; return int.Parse(u);}))();
Run Code Online (Sandbox Code Playgroud)
关键在于转换为a,Func<string,int>然后为select的每次迭代评估lambda (s).任何人都可以提出任何更简单的东西(即,没有强制转换为Func,然后进行评估,或者可能是在保持查询表达式语法的同时实现相同最终结果的不那么冗长的东西)?
注意:上面的lambda内容本质上是微不足道的.请不要改变它.
更新2:是的,这是我,疯狂迈克,回到另一个(更漂亮的?)解决方案:
public static class Lambda
{
public static U Wrap<U>(Func<U> f)
{
return f();
}
}
...
// Then in some function, in some class, in a galaxy far far away:
// Look what we can do with no casts
var res=from string s in test.Split(',')
select Lambda.Wrap(() => {string u="1"+s+"2"; return int.Parse(u);});
Run Code Online (Sandbox Code Playgroud)
我认为这解决了没有丑陋的演员和parenarrhea的问题.类似于Lambda.Wrap泛型方法已经存在于.NET 4.0 Framework的某个地方,所以我不必重新发明轮子吗?不要过度讨论这个问题,我已经将这一点转移到了自己的问题中:.NET 4.0中是否存在这种"Wrap"泛型方法.
假设您使用 LINQ to Objects,您可以只使用辅助方法:
select DoSomethingComplex(s)
Run Code Online (Sandbox Code Playgroud)
如果你不喜欢方法,你可以使用 Func:
Func<string, string> f = s => { Console.WriteLine(s); return s; };
var q = from string s in new[]{"1","2"}
select f(s);
Run Code Online (Sandbox Code Playgroud)
或者,如果您完全一心要把它内联,您可以这样做:
from string s in new[]{"1","2"}
select ((Func<string>)(() => { Console.WriteLine(s); return s; }))()
Run Code Online (Sandbox Code Playgroud)