簡體   English   中英

如何將x => bool的Lambda傳遞給方法,並在Linq Where中使用它?

[英]How can I pass a Lambda of x => bool, to a method, and Use it is a Linq Where?

如何將Lambda謂詞傳遞給方法,並將其用作Linq Where表達式?

編輯清晰度:

我正在嘗試將以下功能添加到StateOverTime<T>

var instanstOfStateOverTimeOfTypeTestType1 = new StatesOverTime<TestType1>();
var result = instanstOfStateOverTimeOfTypeTestType1.TotalTimeWhere(x => x.IsRunning == false)

xT而不是StateOverTime<T>

/編輯

在這行上, var results = States.Where(predicate); 我收到以下語法錯誤

IList<StateOverTime<T>>不包含'Where'的定義,並且最佳擴展方法重載ParallelEnumerable.Where<T>(ParallelQuery<T>, Func<T, bool>)需要類型為ParallelQuery<T>的接收器

這是我的.Net提琴手

https://dotnetfiddle.net/3AyPln

為了完整起見,這是我的示例代碼

using System;
using System.Collections.Generic;
using System.Linq;

namespace StackQuestionLamda
{
    class Program
    {
        static void Main(string[] args)
        {
            var DataStartTime = DateTime.Now;


            var testData = new StatesOverTime<TestType1>();
            testData.States.Add(
                new StateOverTime<TestType1>() {
                    State = new TestType1() { IsRunning = true },
                    Start = DataStartTime.AddMinutes(0),
                    End = DataStartTime.AddMinutes(5)
                });
            testData.States.Add(
                new StateOverTime<TestType1>()
                {
                    State = new TestType1() { IsRunning = false },
                    Start = DataStartTime.AddMinutes(5),
                    End = DataStartTime.AddMinutes(10)
                });
            testData.States.Add(
                new StateOverTime<TestType1>()
                {
                    State = new TestType1() { IsRunning = true },
                    Start = DataStartTime.AddMinutes(10),
                    End = DataStartTime.AddMinutes(15)
                });


            var testData2 = new StatesOverTime<TestType2>();
            testData2.States.Add(
                new StateOverTime<TestType2>()
                {
                    State = new TestType2() { IsRunning = true, IsAlarmed = false },
                    Start = DataStartTime.AddMinutes(0),
                    End = DataStartTime.AddMinutes(5)
                });
            testData2.States.Add(
                new StateOverTime<TestType2>()
                {
                    State = new TestType2() { IsRunning = false, IsAlarmed = true, StatusCode = 99 },
                    Start = DataStartTime.AddMinutes(5),
                    End = DataStartTime.AddMinutes(10)
                });
            testData2.States.Add(
                new StateOverTime<TestType2>()
                {
                    State = new TestType2() { IsRunning = true, IsAlarmed = false },
                    Start = DataStartTime.AddMinutes(10),
                    End = DataStartTime.AddMinutes(15)
                });


            var TotalTimeNotRunning = testData.TotalTimeWhere(x => x.IsRunning == false);

            var TotalTimeIsAlarmed = testData2.TotalTimeWhere(x => x.IsAlarmed == true);

        }
    }


    public class StateOverTime<T>
    {
        public TimeSpan TimeSpan { get => End - Start; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
        public T State { get; set; }

    }

    public class StatesOverTime<T>
    {
        public IList<StateOverTime<T>> States = new List<StateOverTime<T>>();

        public TimeSpan TotalTimeWhere(Func<T, bool> predicate)
        {
            //var results = States.Where(function);
            var results = States.Where(predicate);

            var blah = new TimeSpan(results.Select(x => x.TimeSpan).Sum(x => x.Ticks));

            return blah;
        }
        public double PercentDownTime;
    }

    public class TestType1
    {
        public bool IsRunning { get; set; }
    }

    public class TestType2
    {
        public bool IsRunning { get; set; }
        public bool IsAlarmed { get; set; }
        public int StatusCode { get; set; }
    }
}

您的StatesStateOverTime<T>的集合,您的predicate采用Func<T, bool> 類型不匹配。

您需要將predicate應用於收集項的State屬性,而不是收集項本身:

public class StatesOverTime<T>
{
    public IList<StateOverTime<T>> States = new List<StateOverTime<T>>();

    public TimeSpan TotalTimeWhere(Func<T, bool> predicate)
    {
        //var results = States.Where(function);
        var results = States.Where(state => predicate(state.State));

        var blah = new TimeSpan(results.Select(x => x.TimeSpan).Sum(x => x.Ticks));

        return blah;
    }
    public double PercentDownTime;
}

或者,如果您希望能夠在查詢中使用StateOverTime屬性,則可以使用StateOverTime<T>作為謂詞:

public class StatesOverTime<T>
{
    public IList<StateOverTime<T>> States = new List<StateOverTime<T>>();

    public TimeSpan TotalTimeWhere(Func<StateOverTime<T>, bool> predicate)
    {
        //var results = States.Where(function);
        var results = States.Where(predicate);

        var blah = new TimeSpan(results.Select(x => x.TimeSpan).Sum(x => x.Ticks));

        return blah;
    }
    public double PercentDownTime;
}

在這種情況下,您需要在Main傳遞一個匹配的謂詞:

var TotalTimeNotRunning = testData.TotalTimeWhere(x => x.State.IsRunning == false);

var TotalTimeIsAlarmed = testData2.TotalTimeWhere(x => x.State.IsAlarmed == true);

如評論和其他答案中已經提到的那樣, Func<T, bool>不能直接用作IEnumerable<StateOverTime<T>>謂詞,這需要Func<StateOverTime<T>, bool>

但是,可以通過將傳遞的Func應用於StateOverTime<T>.State屬性來輕松地組成StateOverTime<T>.State如下所示:

var results = States.Where(sot => predicate(sot.State));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM