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();
}