8

Expression<Func<T1,bool>> から Expression<Func<T2,bool>> に変換する方法が見つかりません。私は多くのリフレクションを使用しているため、実際には、型パラメーターを受け取って変換を実行するメソッドが本当に必要です。

public object Convert(Expression<Func<T1,bool>> expr, Type t);

T2 は T1 から派生します。

public class T1 {
     int FamilyId {get; set;}
}

public class T2 : T1 {
     ... other properties
}

基本クラスでフィルター式を定義しています

Expression<Func<T1,bool>> filter = p => p.FamilyId == [some value]

List<T2> に適用したい

4

3 に答える 3

12

これはあなたが探しているものですか?このメソッドには 2 つの種類があります。最初の方法では、新しい入力の型を引数として渡すことができます。2 つ目は、入力タイプをジェネリック パラメーターとして渡し、厳密に型指定された LambdaExpression を取得します。

    public static LambdaExpression ChangeInputType<T, TResult>(Expression<Func<T, TResult>> expression, Type newInputType)
    {
        if (!typeof(T).IsAssignableFrom(newInputType))
            throw new Exception(string.Format("{0} is not assignable from {1}.", typeof(T), newInputType));
        var beforeParameter = expression.Parameters.Single();
        var afterParameter = Expression.Parameter(newInputType, beforeParameter.Name);
        var visitor = new SubstitutionExpressionVisitor(beforeParameter, afterParameter);
        return Expression.Lambda(visitor.Visit(expression.Body), afterParameter);
    }

    public static Expression<Func<T2, TResult>> ChangeInputType<T1, T2, TResult>(Expression<Func<T1, TResult>> expression)
    {
        if (!typeof(T1).IsAssignableFrom(typeof(T2)))
            throw new Exception(string.Format("{0} is not assignable from {1}.", typeof(T1), typeof(T2)));
        var beforeParameter = expression.Parameters.Single();
        var afterParameter = Expression.Parameter(typeof(T2), beforeParameter.Name);
        var visitor = new SubstitutionExpressionVisitor(beforeParameter, afterParameter);
        return Expression.Lambda<Func<T2, TResult>>(visitor.Visit(expression.Body), afterParameter);
    }

    public class SubstitutionExpressionVisitor : ExpressionVisitor
    {
        private Expression before, after;
        public SubstitutionExpressionVisitor(Expression before, Expression after)
        {
            this.before = before;
            this.after = after;
        }
        public override Expression Visit(Expression node)
        {
            return node == before ? after : base.Visit(node);
        }
    }
于 2013-03-04T23:51:01.603 に答える
0

あなたが求めていることは非常に賢明ではありません。T1 を T2 に変換できるかどうか、コンパイラはどのようにして知るのでしょうか? たとえそれが可能であっても、ひどい実行時エラーを要求しているようです.*

(*リフェクションをネストされたジェネリック型と組み合わせようとしているため、可能ではないと思います。)

于 2013-03-04T23:06:57.543 に答える
0

2 つの式を結合したいようです -変換T2し、与えられた結果T1で呼び出すよりも。expr

この質問では、2 つの式の結合 (Expression<Func<T, bool>>)について一般的に説明しています。あなたの場合、変換式を構築するためにExpression.Callが必要であり、変換の結果で元の式を再度呼び出す必要があると思います。

于 2013-03-04T23:09:22.867 に答える