有没有一种方法可以在 C# 中定义隐式运算符,该运算符定义从 Expression 到 selected class 的转换
Is there a way to define implicit operator in C# that defines cast from Expression to selected class
我正在尝试实现定义过滤器的 class,以便在将其作为参数传递给我的存储库 class (EF) 中的方法时更加明确。
而且我对从表达式到 class 的隐式运算符的定义有疑问。
是否可以实现 fd4 变量附近的语法?
public class FilterDefinition<TEntity>
where TEntity : class
{
public FilterDefinition() { }
public FilterDefinition(Expression<Func<TEntity, bool>> filter)
{
this.Filter = filter;
}
public virtual Expression<Func<TEntity, bool>> Filter { get; set; }
public static implicit operator FilterDefinition<TEntity>(Expression<Func<TEntity, bool>> filter) => new FilterDefinition<TEntity>(filter);
}
public class SomeEntity
{
public bool SomeBool { get; set; }
}
class Program
{
static void Main()
{
FilterDefinition<SomeEntity> fd1 = new FilterDefinition<SomeEntity>(x => x.SomeBool);
FilterDefinition<SomeEntity> fd2 = new FilterDefinition<SomeEntity> { Filter = x => x.SomeBool };
FilterDefinition<SomeEntity> fd3 = (Expression<Func<SomeEntity, bool>>)(x => x.SomeBool);
//FilterDefinition<SomeEntity> fd4 = x => x.SomeBool;
Console.ReadKey();
}
}
FilterDefinition class 的目的是作为参数传递给查询的通用存储库。并使用继承定义常用的过滤器。
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
private readonly DbSet<TEntity> dbSet;
public Repository(DbContext context)
{
this.dbSet = context.Set<TEntity>();
}
public async Task<IEnumerable<TEntity>> GetAsync(
FilterDefinition<TEntity> filter = null,
OrderDefinition<TEntity> order = null,
PagingDefinition paging = null)
{
return await new QueryBuilder<TEntity>(this.dbSet)
.ApplyFilter(filter)
.ApplyOrder(order)
.ApplyPaging(paging)
.ToQuery()
.ToListAsync();
}
简短的回答是 "not in this scenario",因为 语法上,在 fd4
中你实际上并不是从 Expression[...]
转换为你的类型。编译器不知道 lambda 代表一个 Expression[...]
,直到它知道它试图用该值做什么; lambda (x => x.SomeBool
) 可以解释为 wide range 两种表达式树类型 and 委托类型(对于匿名方法) ,这里的编译器不会理解你的意思 "treat the lambda as an Expression<Func<SomeEntity, bool>>
, then use the implicit conversion operator to change the expression to a FilterDefinition
"。它根本无法(也不会)实现这一飞跃。你可以接近,就像你的 fd3
例子一样,但是......我的很大一部分人想知道 FilterDefinition
实际上 做了什么 这里,因为到外面观察者它似乎并没有在原始表达式树上添加任何东西。
我正在尝试实现定义过滤器的 class,以便在将其作为参数传递给我的存储库 class (EF) 中的方法时更加明确。
而且我对从表达式到 class 的隐式运算符的定义有疑问。 是否可以实现 fd4 变量附近的语法?
public class FilterDefinition<TEntity>
where TEntity : class
{
public FilterDefinition() { }
public FilterDefinition(Expression<Func<TEntity, bool>> filter)
{
this.Filter = filter;
}
public virtual Expression<Func<TEntity, bool>> Filter { get; set; }
public static implicit operator FilterDefinition<TEntity>(Expression<Func<TEntity, bool>> filter) => new FilterDefinition<TEntity>(filter);
}
public class SomeEntity
{
public bool SomeBool { get; set; }
}
class Program
{
static void Main()
{
FilterDefinition<SomeEntity> fd1 = new FilterDefinition<SomeEntity>(x => x.SomeBool);
FilterDefinition<SomeEntity> fd2 = new FilterDefinition<SomeEntity> { Filter = x => x.SomeBool };
FilterDefinition<SomeEntity> fd3 = (Expression<Func<SomeEntity, bool>>)(x => x.SomeBool);
//FilterDefinition<SomeEntity> fd4 = x => x.SomeBool;
Console.ReadKey();
}
}
FilterDefinition class 的目的是作为参数传递给查询的通用存储库。并使用继承定义常用的过滤器。
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
private readonly DbSet<TEntity> dbSet;
public Repository(DbContext context)
{
this.dbSet = context.Set<TEntity>();
}
public async Task<IEnumerable<TEntity>> GetAsync(
FilterDefinition<TEntity> filter = null,
OrderDefinition<TEntity> order = null,
PagingDefinition paging = null)
{
return await new QueryBuilder<TEntity>(this.dbSet)
.ApplyFilter(filter)
.ApplyOrder(order)
.ApplyPaging(paging)
.ToQuery()
.ToListAsync();
}
简短的回答是 "not in this scenario",因为 语法上,在 fd4
中你实际上并不是从 Expression[...]
转换为你的类型。编译器不知道 lambda 代表一个 Expression[...]
,直到它知道它试图用该值做什么; lambda (x => x.SomeBool
) 可以解释为 wide range 两种表达式树类型 and 委托类型(对于匿名方法) ,这里的编译器不会理解你的意思 "treat the lambda as an Expression<Func<SomeEntity, bool>>
, then use the implicit conversion operator to change the expression to a FilterDefinition
"。它根本无法(也不会)实现这一飞跃。你可以接近,就像你的 fd3
例子一样,但是......我的很大一部分人想知道 FilterDefinition
实际上 做了什么 这里,因为到外面观察者它似乎并没有在原始表达式树上添加任何东西。