C# 反转表达式的正确方法<;Func<;T、 布尔>&燃气轮机; 公共静态类谓词生成器 { 公共静态表达式处于活动状态(DateTime effectiveDate) 地点:IValidFromTo { 返回e=>(e.EffectiveFrom==null | | e.EffectiveFrom.Value.Date effectiveDate.Date); } 公共静态表达式活动(日期时间有效日期),其中tenty:IValidFromTo { var isActive=活动(生效日期); 返回Expression.Lambda(Expression.Not(isActive.Body),isActive.Parameters[0]); } } 公共接口IValidFromTo { 公共日期时间?从{get;}开始生效 公共日期时间?对{get;}有效 } 公共类产品:IValidFromTo { 公共产品(int id) { Id=Id; } 私有int Id{get;set;} 公共日期时间?从{get;set;}开始生效 public DateTime?EffectiveTo{get;set;} } 静态void Main(字符串[]参数) { var products=新列表() { 新产品(1){EffectiveFrom=DateTime.Now.Date.AddMonths(-1),EffectiveTo=DateTime.Now.Date.AddDays(-1)}, 新产品(2){EffectiveFrom=DateTime.Now.Date,EffectiveTo=DateTime.Now.AddDays(1)}, 新产品(3){EffectiveFrom=DateTime.Now.Date.AddMonths(1),EffectiveTo=null}, }; var activeExpression=PredicateBuilder.Active (DateTime.Now.Date).Compile(); var activeProducts=products.Where(activeExpression.ToList(); `var inactiveExpression=PredicateBuilder.Inactive (DateTime.Now.Date).Compile(); var inactiveProducts=products.Where(inactiveExpression.ToList(); Console.ReadKey(); }
这段代码运行良好。当我使用C# 反转表达式的正确方法<;Func<;T、 布尔>&燃气轮机; 公共静态类谓词生成器 { 公共静态表达式处于活动状态(DateTime effectiveDate) 地点:IValidFromTo { 返回e=>(e.EffectiveFrom==null | | e.EffectiveFrom.Value.Date effectiveDate.Date); } 公共静态表达式活动(日期时间有效日期),其中tenty:IValidFromTo { var isActive=活动(生效日期); 返回Expression.Lambda(Expression.Not(isActive.Body),isActive.Parameters[0]); } } 公共接口IValidFromTo { 公共日期时间?从{get;}开始生效 公共日期时间?对{get;}有效 } 公共类产品:IValidFromTo { 公共产品(int id) { Id=Id; } 私有int Id{get;set;} 公共日期时间?从{get;set;}开始生效 public DateTime?EffectiveTo{get;set;} } 静态void Main(字符串[]参数) { var products=新列表() { 新产品(1){EffectiveFrom=DateTime.Now.Date.AddMonths(-1),EffectiveTo=DateTime.Now.Date.AddDays(-1)}, 新产品(2){EffectiveFrom=DateTime.Now.Date,EffectiveTo=DateTime.Now.AddDays(1)}, 新产品(3){EffectiveFrom=DateTime.Now.Date.AddMonths(1),EffectiveTo=null}, }; var activeExpression=PredicateBuilder.Active (DateTime.Now.Date).Compile(); var activeProducts=products.Where(activeExpression.ToList(); `var inactiveExpression=PredicateBuilder.Inactive (DateTime.Now.Date).Compile(); var inactiveProducts=products.Where(inactiveExpression.ToList(); Console.ReadKey(); },c#,C#,这段代码运行良好。当我使用(!)获取非活动产品而不是创建inactive()方法时,提出了我的问题 如果将非活动产品编码为: var incativeProducts=products.Where(PredicateBuilder.Active(DateTime.Now.Date.Compile()).ToList()编译器不会抱怨(!),但结果与activeProducts相同。基本上,(!)在该上下文中不进行反转 这是预期的结果吗?或者,如果没有上述方法,反转活动的正确方法是什么?您可以将代
(!)
获取非活动产品而不是创建inactive()
方法时,提出了我的问题
如果将非活动产品编码为:
var incativeProducts=products.Where(PredicateBuilder.Active(DateTime.Now.Date.Compile()).ToList()代码>编译器不会抱怨(!),但结果与activeProducts
相同。基本上,(!)
在该上下文中不进行反转
这是预期的结果吗?或者,如果没有上述方法,反转活动的正确方法是什么?您可以将代码示例简化为仅对问题部分有意义吗?不是问题的一部分,但您的代码编写时效率极低,它同时调用DateTime。现在
和Expression.Compile()
用于源集合中的每一项。在调用Where
之前编译表达式。还尝试了此编译异常“Operator”!'无法应用于我得到的“Expression”类型的操作数。您可能没有注意到我的调用中的lambda参数,其中
显示您尝试的代码。是的,您是对的!。我确实忽略了(w)
部分。谢谢。我推荐代码审查网站,但是如果你想了解性能,让处于非活动状态将需要单独编译,这显然需要使用内存和处理能力来实际生成IL,然后JIT编译它。另外,它不容易从调用方进行扩展,这与实际的lambda函数不同,您可以根据需要编写lambda函数,这可能只是添加了一个代码>在开头。
public static class PredicateBuilder
{
public static Expression<Func<TEntity, bool>> Active<TEntity>(DateTime effectiveDate)
where TEntity : IValidFromTo
{
return e => (e.EffectiveFrom == null || e.EffectiveFrom.Value.Date <= effectiveDate.Date) &&
(e.EffectiveTo == null || e.EffectiveTo.Value.Date > effectiveDate.Date);
}
public static Expression<Func<TEntity, bool>>Inactive<TEntity>(DateTime effectiveDate) where TEntity : IValidFromTo
{
var isActive = Active<TEntity>(effectiveDate);
return Expression.Lambda<Func<TEntity, bool>>(Expression.Not(isActive.Body), isActive.Parameters[0]);
}
}
public interface IValidFromTo
{
public DateTime? EffectiveFrom { get; }
public DateTime? EffectiveTo { get; }
}
public class Product: IValidFromTo
{
public Product(int id)
{
Id = id;
}
private int Id { get; set; }
public DateTime? EffectiveFrom { get; set; }
public DateTime? EffectiveTo { get; set; }
}
static void Main(string[] args)
{
var products = new List<Product>()
{
new Product(1){ EffectiveFrom =DateTime.Now.Date.AddMonths(-1),EffectiveTo = DateTime.Now.Date.AddDays(-1)},
new Product(2){ EffectiveFrom = DateTime.Now.Date, EffectiveTo=DateTime.Now.AddDays(1)},
new Product(3){ EffectiveFrom =DateTime.Now.Date.AddMonths(1), EffectiveTo = null},
};
var activeExpression = PredicateBuilder.Active<Product>
(DateTime.Now.Date).Compile();
var activeProducts= products.Where(activeExpression).ToList();
`var inactiveExpression = PredicateBuilder.Inactive<Product>
(DateTime.Now.Date).Compile();
var inactiveProducts= products.Where(inactiveExpression ).ToList();
Console.ReadKey();
}
var incativeProducts = products
.Where(PredicateBuilder.Active<Product>(DateTime.Now.Date).Compile()!)
.ToList();
var incativeProducts = products
.Where(w => !PredicateBuilder.Active<Product>(DateTime.Now.Date).Compile()(w))
.ToList();