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