[英]C# anonymous function inside lambda
I'm trying to work out the syntax for using an anonymous function inside the lambda of a linq .Where() call. 我正在尝试在linq .Where()调用的lambda中使用匿名函数的语法。
I'm using the Where to filter certain items from a list. 我正在使用“位置”从列表中筛选某些项目。
I want each part of the filter logic inside the Where. 我希望过滤逻辑的每个部分都在Where中。 The logic is only useful inside the filter so I don't want to have to define any functions outside. 该逻辑仅在过滤器内部有用,因此我不想在外部定义任何函数。
Here's a simplified & generalised example: 这是一个简化的通用示例:
var filtered = myEnumerable.Where(item =>
item.PropertyA == 1 ||
item.PropertyB == 2 ||
item =>
{
var heavyResult = GetStuff(item); // Some heavyweight processing
return heavyResult.IsSomethingTrue() && heavyResult.IsSomethingElseTrue();
});
So I want the third line in the Where() to be an anonymous function taking item and returning a boolean. 因此,我希望Where()中的第三行是一个匿名函数,接受项目并返回一个布尔值。
Also, the function being called after the checks on PropertyA and PropertyB is intended to limit having to call GetStuff() if either of those lightweight comparisons already evaluated as true. 同样,在检查PropertyA和PropertyB之后调用的函数旨在限制如果那些轻量级比较中的任何一个已被评估为true,则必须调用GetStuff()。
I can't do it all inline because I need to evaluate two properties from heavyResult. 我无法内联完成所有操作,因为我需要评估heavyResult中的两个属性。
This seems like it should be simple, but I don't seem to be able to find the right syntax, either by experimenting or Googling. 这似乎应该很简单,但是我似乎无法通过实验或谷歌搜索找到正确的语法。
I can't do it all inline because I need to evaluate two properties from heavyResult. 我无法内联完成所有操作,因为我需要评估heavyResult中的两个属性。
You can do it inline, its just you need to wrap the entire thing in {}
and use the return
keyword. 您可以内联完成它,只需要将整个内容包装在{}
并使用return
关键字即可。
var filtered = myEnumerable.Where(item =>
{
var test = item.PropertyA == 1 || item.PropertyB == 2;
if(test)
return true;
var heavyResult = GetStuff(item); // Some heavyweight processing
return heavyResult.IsSomethingTrue() && heavyResult.IsSomethingElseTrue();
});
To be honest though - doing something that even that simple inline is probably the wrong choice. 不过,老实说-即使执行简单的内联操作也可能是错误的选择。 Extract it into a function, with a meaningful name, and your code is self documenting 将其提取到具有有意义名称的函数中,并且您的代码可以自我记录
var filtered = myEnumerable.Where(ADescriptiveNamedFunctionSelfDocumentsYourCode);
Firstly, multiline lambdas are a really bad idea. 首先,多行lambda是个坏主意。
They were intended as simple functional representations f(x)= ...
stuff. 它们旨在作为简单的功能表示f(x)= ...
东西。
You can't do this the way you're thinking because you first want to call a function, capture its result, & then call 2 different methods on that object. 您无法按照您的想法进行操作,因为您首先要调用一个函数,捕获其结果,然后在该对象上调用2个不同的方法。
You can do this more simply by moving the delegate out of the lambda. 您可以通过将委托移出lambda来更简单地执行此操作。
The latest version of C# supports local functions, which may be what you want. 最新版本的C#支持本地功能,这可能是您想要的。 But you can still do this with anonymous functions in C# 6. 但是您仍然可以使用C#6中的匿名函数来执行此操作。
I've also shown how you can do this with another method in HeavyResult
or an extension method it's not feasible to change HeavyResult
. 我还展示了如何使用HeavyResult
另一种方法或扩展方法来执行此操作,而该方法无法更改HeavyResult
。
In the code below, you would use only one of the options from 在下面的代码中,您将仅使用以下选项之一
validator(item) ||
GetStuff(item).IsAllTrue() ||
GetStuff(item).IsAllTrueExt()
Here's the full code: 这是完整的代码:
public static class Program
{
static void Main(string[] args)
{
var myEnumerable = new List<int>() { 1, 2, 3, 4, 5 };
Predicate<int> validator;
validator = delegate (int item)
{
var heavyResult = GetStuff(item);
return heavyResult.IsSomethingTrue() && heavyResult.IsSomethingElseTrue();
};
var filtered = myEnumerable.Where(item =>
item >= 1 ||
item <= 200 ||
validator(item) ||
GetStuff(item).IsAllTrue() ||
GetStuff(item).IsAllTrueExt()
);
}
public static bool IsAllTrueExt(this HeavyResult hr)
{
{ return hr.IsSomethingTrue() && hr.IsSomethingElseTrue(); }
}
public static HeavyResult GetStuff(int item)
{
return new HeavyResult(item);
}
public class HeavyResult
{
public HeavyResult(int value)
{
Value = value;
}
int Value { get; }
public bool IsSomethingTrue()
{
{ return Value >= 5; }
}
public bool IsSomethingElseTrue()
{
{ return Value <= 50; }
}
public bool IsAllTrue()
{
{ return IsSomethingTrue() && IsSomethingElseTrue(); }
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.