Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在运行时在C中更改IObservable Func谓词_C#_System.reactive_Reactive_Dynamic Data_Rx.net - Fatal编程技术网

C# 如何在运行时在C中更改IObservable Func谓词

C# 如何在运行时在C中更改IObservable Func谓词,c#,system.reactive,reactive,dynamic-data,rx.net,C#,System.reactive,Reactive,Dynamic Data,Rx.net,我不熟悉动态数据和一般的反应式扩展,我目前面临以下问题,我想在运行时使用动态数据包,从而使用.NETC中的反应式扩展来更改IObservable谓词 考虑到以下情况,我有一个DataGrid,其中一些列的类型为integer,比如a、B、C。此外,还有一个过滤器UI,用户可以在其中添加多个过滤器,如a==6或过滤器表达式的组合,如a==7 | | a==3 | | B==5等。因此,基本上我返回Func委托的方法如下所示: private Func<T, bool> FilterOn

我不熟悉动态数据和一般的反应式扩展,我目前面临以下问题,我想在运行时使用动态数据包,从而使用.NETC中的反应式扩展来更改IObservable谓词

考虑到以下情况,我有一个DataGrid,其中一些列的类型为integer,比如a、B、C。此外,还有一个过滤器UI,用户可以在其中添加多个过滤器,如a==6或过滤器表达式的组合,如a==7 | | a==3 | | B==5等。因此,基本上我返回Func委托的方法如下所示:

private Func<T, bool> FilterOnA(string id)
{
    return n => n.Id == int.Parse(id);
}
public IObservable<Func<T,bool>> Filter1 {get;} 
public IObservable<Func<T,bool>> Filter2 {get;}
public IObservable<Func<T,bool>> Filter3 {get;}
public IObservable<Func<T,bool>> FilterX {get;}

public IObservable<Func<T,bool>> AllFiltersCombined => Filter1.CombineLatest(Filter2,Filter3,FilterX, (f1,f2,f3,fx) => AggregatePredicatesAnd(f1,f2,f3,fx));


public static Func<T,Bool> AggregatePredicatesAnd(params Func<T,bool>[] predicates) 
{
    return predicates.Aggregate<Func<T,bool>>((fa,fb) => (T t) => fa(t) && fb(t));
}
以及数据管道中的筛选器方法调用:

    // sourceList is used to fill the ReadOnlyObservableCollection<T> while receiving data from an event pattern

    sourceList.Connect()                        // SourceList<T>
              .Filter(filterViewModel.FilterOnA)
              .Bind(out _itemsBinding)          // private ReadOnlyObservableCollection<T>
              .DisposeMany()
              .Subscribe();
正如我上面提到的,用户应该能够添加/删除/修改,更重要的是将过滤器表达式组合在一起

由于dynamic的数据筛选器方法采用Func或IObservable,因此一种可能的解决方案可能如下所示:

private Func<T, bool> FilterOnA(string id)
{
    return n => n.Id == int.Parse(id);
}
public IObservable<Func<T,bool>> Filter1 {get;} 
public IObservable<Func<T,bool>> Filter2 {get;}
public IObservable<Func<T,bool>> Filter3 {get;}
public IObservable<Func<T,bool>> FilterX {get;}

public IObservable<Func<T,bool>> AllFiltersCombined => Filter1.CombineLatest(Filter2,Filter3,FilterX, (f1,f2,f3,fx) => AggregatePredicatesAnd(f1,f2,f3,fx));


public static Func<T,Bool> AggregatePredicatesAnd(params Func<T,bool>[] predicates) 
{
    return predicates.Aggregate<Func<T,bool>>((fa,fb) => (T t) => fa(t) && fb(t));
}

现在,我的问题是,如何用一种更通用的方式来写这个?如何组合,例如0到n个过滤器?不同的过滤器类型是什么,例如a的组合,您可以使用如下所示的ApplyFilters操作:

公共静态类扩展 { 公共静态列表应用程序此列表列表,操作 { 行动清单; 退货清单; } 公共静态IObservable应用程序过滤器此IObservable源、IObservable AddFilter、IObservable RemoveFilter { //将AddFilter项目添加到func,该func将筛选器添加到筛选器列表中 var adding=AddFilter.Selectfunc=>Actionlist=>list.Addfunc; //将RemoveFilter投影到从筛选器列表中删除筛选器的func var removing=RemoveFilter.Selectfunc=>Actionlist=>list.Removefunc; //返回一个可观察到的。。。 可观测回波 //…合并添加和删除操作。。。 .merge添加、删除 //…并将其应用于初始为空的列表。。。 .scan新列表,列表,更改=>List.Applychange //…并将每个列表更改投影到新的可观察对象 //通过将所有操作应用于可观测的源。。。 .Selectlist=>list.Aggregatesource,s,f=>s.Wheref //…并最终订阅了新的可观测 转换 } } 公共类视图模型 { 公共可观测源; 公共IObservable\u addFilter; 公共IObservable _removeFilter; 公共视图模型 { FilteredItems=\u source.ApplyFilters\u addFilter,\u removeFilter; } 公共IObservable FilteredItems{get;} } 公共类项{} 限制:

未考虑函数等价性。您可能需要强键入每个筛选器func,以确保能够从筛选器的内部列表中正确添加/删除它

没有考虑分组和| |运算,即A==7&&B==Hello | | C==1。如果这一点很重要,您肯定需要根据1强键入筛选器并添加组标识符。然后,在对可观察对象执行聚合之前,可以在列表上使用GroupBy


与ibeebs答案不同,我还发现了另一种可能的解决方案。为了构建过滤器的可能组合,可以使用动态表达式库: 并创建如下表达式:

Expression<Func<T, bool>> e2 = DynamicExpression.ParseLambda<T, bool>("Id == 7 or Id == 9");
或者更复杂的

因为我在问题中提到,用户可以通过UI创建过滤器,所以构建Id==7或Id==9这样的字符串表达式并不是什么大问题


这样的表达式可以简单地编译成Func。

在集合中存储Filter1..X而不是显式属性怎么样?或者至少将这些属性映射到底层集合?实际上,它们是在观察集合中的:但是,我可以考虑将过滤器分离,例如不同的列。即使在集合中,我也不知道如何在这个聚合函数中构建/组合不同的运算符;为什么每个过滤器都是一个IObservable而不是一个Func?你不能只更新Func谓词。。。不会指定新表达式。请参阅文档:过滤部分。谢谢您的回答!我将把这个标记为有用。