Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 如何创建谓词<;T>;运行时动态_C#_Linq_Lambda_Expression Trees_Predicate - Fatal编程技术网

C# 如何创建谓词<;T>;运行时动态

C# 如何创建谓词<;T>;运行时动态,c#,linq,lambda,expression-trees,predicate,C#,Linq,Lambda,Expression Trees,Predicate,我试图在基类中创建一个方法,该方法能够获取参数并动态创建谓词 下面是抽象类: public abstract class Table<TResults> where TResults : class { ... protected abstract List<TResults> Results { get; set; } ... } 公共抽象类表 结果:课堂 { ... 受保护的抽象列表结果{get;set;} ... } 下面是一个实

我试图在基类中创建一个方法,该方法能够获取参数并动态创建
谓词

下面是抽象类:

public abstract class Table<TResults>
    where TResults : class
{
    ...
    protected abstract List<TResults> Results { get; set; }
    ...
}
公共抽象类表
结果:课堂
{
...
受保护的抽象列表结果{get;set;}
...
}
下面是一个实现
的类:

公共班级学生
{
...
公共字符串名称=>//一些代码
...
公共作废检查()
{
//检查执行情况
}
}
公共类表学生:表
{
...
受保护的覆盖列表结果{get;set;}
...
public void Check_Student(string studentName)=>Results.Find(r=>r.Name==studentName.Check();
}
下面是另一个实现
表的类:

public-class-TrAnswer
{
...
公共字符串名称=>//一些代码
public int Id=>//其他一些代码
...
公开无效报告()
{
//报告执行情况
}
}
公共课表格答案:表格
{
...
受保护的覆盖列表结果{get;set;}
...
public void Report_Answer(字符串answerName,int answerId)=>Results.Find(r=>r.Name==answerName&&r.Id==answerId).Report();
...
}
如果可能的话,我想做的是将
类更新为:

public abstract class Table<TResults>
    where TResults : class
{
    ...
    protected abstract List<TResults> Results { get; set; }
    ...
    protected abstract Predicate<T> Predicate { get; }
    protected T Find(parameters) => Results.Find(parameters, Predicate);
}
公共抽象类表
结果:课堂
{
...
受保护的抽象列表结果{get;set;}
...
受保护的抽象谓词{get;}
受保护的T Find(参数)=>Results.Find(参数,谓词);
}
因此,我可以将派生类更新为:

public class TableStudents : Table<TrStudent>
{
    ...        
    public void Check_Student(string studentName) => Find(studentName).Check();
}

public class TableAnswers<TrAnswer> : Table<TrAnswer>
{
    ...       
    public void Report_Answer(string answerName, int answerId) => Find(answerName, answerId).Report();
}
公共类表学生:表
{
...        
public void Check_Student(字符串studentName)=>Find(studentName.Check();
}
公共课表格答案:表格
{
...       
public void Report_Answer(字符串answerName,int answerId)=>Find(answerName,answerId).Report();
}
但我不确定这是否可行,因为有些lambda比其他lambda需要更多的参数

我已经检查过了,而且我几乎肯定这是可以做到的,但我不知道从哪里开始


谢谢您的时间。

以下选项不适用吗

公共抽象类表,其中TResults:class{
// ...
受保护的TResults Find(谓词)
=>Results.Find(谓词);
}
公共类表学生:表{
// ...
公共无效检查\u学生(字符串studentName)
=>Find(r=>r.Name==studentName).Check();
}
公共类表格答案:表格
{
// ...
公共无效报告\u应答(字符串应答名称,int应答ID)
=>Find(r=>r.Name==answerName&&r.Id==answerId.Report();
}
我看不出在运行时使用hazzle创建
谓词
有什么意义


老实说,通常情况下,您的解决方案看起来有点设计过度。当每个子类都必须重写结果的
List
时,抽象
List.Find()
有什么意义

这些子类实际上拥有过滤结果所需的一切(即结果本身和谓词参数),但它们仍然必须要求抽象基类过滤它们


如果您多次需要谓词,您可以在每个子类中使用私有函数,为给定参数返回
谓词

公共类表学生:表{
// ...
公共无效检查\u学生(字符串studentName)
=>查找(FilterBy(studentName)).Check();
专用静态谓词筛选器by(字符串studentName)
=>r=>r.Name==studentName;
}
公共类表格答案:表格
{
// ...
公共无效报告\u应答(字符串应答名称,int应答ID)
=>Find(FilterBy(answerName,answerId)).Report();
专用静态谓词过滤器by(字符串answerName,int answerId)
=>r=>r.Name==answerName和&r.Id==answerId;
}
不要因为这些私有的
FilterBy()
函数具有相同的名称和类似的工作方式而被迫将它们提取到基类中。如何过滤子类与基类无关。子类最了解如何过滤其结果,它可能会也可能不会使用一个或多个私有函数来创建所需的
谓词


请注意,
FilterBy()
是一个返回
谓词的函数。
谓词
是一个函数对象,当您给它一个
T
值时,它返回一个
bool

它类似于像
bool MyPredicate(T value){…}
这样的常规函数,只是您可以将它存储在变量中,传递它,甚至从其他函数返回它:

//创建函数对象
var isAlphaNumeric=新谓词(c=>char.islitter(c)| | char.IsDigit(c));
//使用某些值调用函数对象
Assert(isAlphaNumeric('a')==true);
Assert(isAlphaNumeric('&')==false);
FilterBy()
的这个更详细的版本可能会使与
isAlphaNumeric
的关系更加清晰:

private静态谓词过滤器by(string studentName){
var hasName=new谓词(r=>r.Name==studentName);
返回hasName;
}
isAlphaNumeric
hasName
之间的主要区别在于
hasName
需要通过将
studentName
参数存储在函数对象中来捕获其值。稍后,当使用一个或多个
TrStudent
对象调用返回的
hasName
函数对象时,该值将可用于名称比较


顺便说一下,返回函数(或将其他函数作为参数)的函数称为。C#take
public abstract class Table<TResults>
    where TResults : class
{
    ...
    protected abstract List<TResults> Results { get; set; }
    ...
    protected abstract Predicate<T> Predicate { get; }
    protected T Find(parameters) => Results.Find(parameters, Predicate);
}
public class TableStudents : Table<TrStudent>
{
    ...        
    public void Check_Student(string studentName) => Find(studentName).Check();
}

public class TableAnswers<TrAnswer> : Table<TrAnswer>
{
    ...       
    public void Report_Answer(string answerName, int answerId) => Find(answerName, answerId).Report();
}