繁体   English   中英

Lambda内的C#匿名函数

[英]C# anonymous function inside lambda

我正在尝试在linq .Where()调用的lambda中使用匿名函数的语法。

我正在使用“位置”从列表中筛选某些项目。

我希望过滤逻辑的每个部分都在Where中。 该逻辑仅在过滤器内部有用,因此我不想在外部定义任何函数。

这是一个简化的通用示例:

var filtered = myEnumerable.Where(item =>
    item.PropertyA == 1 ||
    item.PropertyB == 2 ||
    item => 
    {
        var heavyResult = GetStuff(item); // Some heavyweight processing
        return heavyResult.IsSomethingTrue() && heavyResult.IsSomethingElseTrue();
    });

因此,我希望Where()中的第三行是一个匿名函数,接受项目并返回一个布尔值。

同样,在检查PropertyA和PropertyB之后调用的函数旨在限制如果那些轻量级比较中的任何一个已被评估为true,则必须调用GetStuff()。

我无法内联完成所有操作,因为我需要评估heavyResult中的两个属性。

这似乎应该很简单,但是我似乎无法通过实验或谷歌搜索找到正确的语法。

我无法内联完成所有操作,因为我需要评估heavyResult中的两个属性。

您可以内联完成它,只需要将整个内容包装在{}并使用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();
    });

不过,老实说-即使执行简单的内联操作也可能是错误的选择。 将其提取到具有有意义名称的函数中,并且您的代码可以自我记录

var filtered = myEnumerable.Where(ADescriptiveNamedFunctionSelfDocumentsYourCode);

首先,多行lambda是个坏主意。

它们旨在作为简单的功能表示f(x)= ...东西。

您无法按照您的想法进行操作,因为您首先要调用一个函数,捕获其结果,然后在该对象上调用2个不同的方法。

您可以通过将委托移出lambda来更简单地执行此操作。

最新版本的C#支持本地功能,这可能是您想要的。 但是您仍然可以使用C#6中的匿名函数来执行此操作。

我还展示了如何使用HeavyResult另一种方法或扩展方法来执行此操作,而该方法无法更改HeavyResult

在下面的代码中,您将仅使用以下选项之一

validator(item) ||
GetStuff(item).IsAllTrue() ||
GetStuff(item).IsAllTrueExt()

这是完整的代码:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM