[英]Convert Expression<Func<T,T,bool>> to Expression<Func<T,bool>>
[英]Cannot convert from Expression<Func<T,bool>> to Expression<Func<User,bool>> when T = User within class
所以说我有这个 class 和方法, Store.Users
的上下文。 Get
的类型为User
。 但是,当我将方法参数设置为Expression<Func<T,bool>>
并将其作为Get()
方法的表达式传递时。 我收到 IDE & build 错误说明:
Argument 1 : cannot convert from Expression<Func<T,bool>> to Expression<Func<User,bool>>.
'Argument Type: Expression<Func<T,bool>> is not assignable to parameter type Expression<Func<User,bool>>'.
除了本例之外,代码的所有其他部分都能够识别T
的类型为User
。 任何提示/想法都会很棒。
public class Builder<T> : DataBuilder<T> where T : User
{
public override T Exists(Expression<Func<T, bool>> predicateExpression)
{
return Store.Users.Get(predicateExpression).FirstOrDefault();
}
}
另一种选择是修改Expression
以使用as
转换为正确的类型 - 但是,传入错误的类型将导致运行时异常,并且这样做会产生一些轻微的开销。
首先,您需要一个ExpressionVisitor
来替换Expression
中的Expression
(感觉应该是内置的):
public static class ExpressionExt {
/// <summary>
/// Replaces an Expression (reference Equals) with another Expression
/// </summary>
/// <param name="orig">The original Expression.</param>
/// <param name="from">The from Expression.</param>
/// <param name="to">The to Expression.</param>
/// <returns>Expression with all occurrences of from replaced with to</returns>
public static Expression Replace(this Expression orig, Expression from, Expression to) => new ReplaceVisitor(from, to).Visit(orig);
/// <summary>
/// ExpressionVisitor to replace an Expression (that is Equals) with another Expression.
/// </summary>
public class ReplaceVisitor : ExpressionVisitor {
readonly Expression from;
readonly Expression to;
public ReplaceVisitor(Expression from, Expression to) {
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node) => node == from ? to : base.Visit(node);
}
}
然后,您可以使用它用适当as
包装原始Expression
参数:
public class Builder<T> : DataBuilder<T> where T : User {
public override T Exists(Expression<Func<T, bool>> predicateExpression) {
var p = predicateExpression.Parameters[0];
var pAsUser = Expression.MakeUnary(ExpressionType.TypeAs, p, typeof(User));
var b = predicateExpression.Body.Replace(p, pAsUser);
var newpe = Expression.Lambda<Func<User, bool>>(b, p);
return (T)Store.Users.Get(newpe).FirstOrDefault();
}
}
由于 T 是 User 类型,您可以在下面尝试
public class Builder<T> : DataBuilder<T> where T : User
{
public override T Exists(Expression<Func<T, bool>> predicateExpression)
{
Expression<Func<User, bool>> expr =
Expression.Lambda<Func<User, bool>>(predicateExpression.Body,
predicateExpression.Parameters);
return Store.Users.Get(expr).FirstOrDefault();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.