Reputation: 6758
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();
}
This code works fine. My question was raised when I use(!)
to get inactive products instead of creating Inactive()
method.
If you code for inactiveProducts as:
var incativeProducts= products.Where(PredicateBuilder.Active<Product>(DateTime.Now.Date).Compile()!).ToList();
compiler does not complain about the (!) but the result is the same as activeProducts
. Basically (!)
does not do inversion in that context.
Is this expected outcome? Or what would be the correct way of inverting the Active without having a method like above?
Upvotes: 0
Views: 96
Reputation: 67380
var incativeProducts = products
.Where(PredicateBuilder.Active<Product>(DateTime.Now.Date).Compile()!)
.ToList();
!
in that context does not mean "not", it's a C# 8 feature that means that the nullable returned by Compile()
is expected by you to not be null
. If you want to negate an expression, the unary !
operator sits, like every other unary operator, at the beginning:
var incativeProducts = products
.Where(w => !PredicateBuilder.Active<Product>(DateTime.Now.Date).Compile()(w))
.ToList();
Upvotes: 1