繁体   English   中英

无法从表达式转换<func<t,bool> &gt; 到表达式<func<user,bool> &gt; 当 T = class 内的用户时</func<user,bool></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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM