C# 基于<;在运行时动态创建搜索表单;T>;性质

C# 基于<;在运行时动态创建搜索表单;T>;性质,c#,generics,runtime,func,C#,Generics,Runtime,Func,我正在WindowsForm应用程序中创建搜索表单: public partial class SearchForm<T>() { .... } 搜索表单如下所示: 对于字符串属性,我希望有一个文本框,对于数字属性,有2个控件(一个用于From,另一个用于To) 此外,我还想将用户选择的条件放在谓词变量中: Func<T, bool> predicate; Func谓词; 比如说 predicate = t => t.OrderNumber.Conta

我正在WindowsForm应用程序中创建搜索表单:

public partial class SearchForm<T>()
{
   ....
}
搜索表单如下所示:

对于
字符串
属性,我希望有一个
文本框
,对于数字属性,有2个
控件
(一个用于From,另一个用于To)

此外,我还想将用户选择的条件放在
谓词
变量中:

Func<T, bool> predicate;
Func谓词;
比如说

predicate = t => t.OrderNumber.Contains("ORDER-01") && 
                 t.OrderWeight >= 100 &&
                 t.OrderWeight <= 200;
predicate=t=>t.OrderNumber.Contains(“ORDER-01”)&&
t、 订单重量>=100&&

t、 OrderWeight要获得类型的属性,可以依赖反射。看

然后,您可以使用表达式树来构建动态谓词。看

但我建议采用一种更简单(但涉及更多类型)的方法

拥有一个应该由所有
T
s实现的接口。比如:

 public interface Searchable
 {
      IEnumerable<ParamInfo> Params { get; }
      Func<string, decimal, decimal, bool> Predicate { get; }
 }
您的搜索表单可以

public partial class SearchForm<T> where T : Searchable
{
   ....
}
public分部类SearchForm,其中T:Searchable
{
....
}
和poco:

public class Order : Searchable
{
   public string OrderNumber {get; set;}
   public decimal OrderWeight {get; set;}

   public IEnumerable<ParamInfo> Params 
   {  
      get 
      { 
          return new List<ParamInfo> 
          {
              new ParamInfo(typeof(TextBox), typeof(string), "Enter value", true),
              new ParamInfo(typeof(TextBox), typeof(decimal), 0, true),
              new ParamInfo(typeof(TextBox), typeof(decimal), 0, true)
          }
      }  
   }

   public Func<string, decimal, decimal, bool> Predicate
   {  
      get 
      { 
          return (s, d1, d2) => OrderNumber.Contains(s) 
                             && OrderWeight >= d1 
                             && OrderWeight <= d2; //and so on, u get the idea.
      }  
   }
公共类顺序:可搜索
{
公共字符串OrderNumber{get;set;}
公共十进制OrderWeight{get;set;}
公共IEnumerable参数
{  
得到
{ 
返回新列表
{
新的ParamInfo(typeof(文本框)、typeof(字符串)、“输入值”、true),
新的ParamInfo(typeof(文本框)、typeof(十进制)、0、true),
新的ParamInfo(typeof(文本框)、typeof(十进制)、0、true)
}
}  
}
公共Func谓词
{  
得到
{ 
return(s、d1、d2)=>OrderNumber.Contains
&&订单重量>=d1
&&OrderWeight1)通过反射获取有关属性的信息,使用PropertyType按类型筛选

PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
return properties.Where(p => p.PropertyType == typeof(string));
2) 由于
谓词的返回类型是
bool
,因此获得所需结果的简单方法是:

public Func<T, bool> AllTrue<T>(IEnumerable<Func<T, bool>> predicates)
{
    return t => predicates.All(p => p(t));
}
public Func AllTrue(IEnumerable谓词)
{
返回t=>predicates.All(p=>p(t));
}

谢谢,但我不想像yo所说的那样从Order获得修复谓词,我想基于最终用户生成谓词inputs@Masoud这没什么大不了的。取而代之的是
Func
,取而代之的是
Func
,但如果用户没有在Orderweight文本框中输入任何值,我不希望在谓词中包含Orderweight,也不希望启用。@Masoud我的意图是至于给你一个(替补)如何解决这个问题,这不是一个非常精确、经过测试的函数库:)您当然可以根据您的需要来构建它。我的方法确实提供了定制的灵活性。在您的情况下,您可以检查OrderWeight是否为零,并退出Order类中的谓词。如果0是有效值,则让您的func be
func
并检查文本框值,等等。如果需要,您甚至可以让它们都是通用的。最后,这种方法设计得更好,应该更快
PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
return properties.Where(p => p.PropertyType == typeof(string));
public Func<T, bool> AllTrue<T>(IEnumerable<Func<T, bool>> predicates)
{
    return t => predicates.All(p => p(t));
}