是否有轉換表達<Func鍵<in T, bool>>或表達<Func鍵<TBase,bool>>表達式<Func<T,bool>>轉換器
Expression<Func<TBase,bool>>
到
Expression<Func<T,bool>>
其中T是從TBASE繼承的任何簡單的方法?
是否有轉換表達<Func鍵<in T, bool>>或表達<Func鍵<TBase,bool>>表達式<Func<T,bool>>轉換器
Expression<Func<TBase,bool>>
到
Expression<Func<T,bool>>
其中T是從TBASE繼承的任何簡單的方法?
只要爲T從TBASE派生,你可以直接創建所需的類型與表達您的原始表情的身體和參數。
Expression<Func<object, bool>> x = o => o != null;
Expression<Func<string, bool>> y = Expression.Lambda<Func<string, bool>>(x.Body, x.Parameters);
您可能需要手動進行轉換。這是因爲你正在有效地將其轉換爲可能的子集。所有T
均爲TBase
,但並非全部TBase
均爲T
。
好消息是,您可以使用Expression.Invoke進行手動操作,並手動將相應的演員表轉換爲TBase
(當然可以捕捉任何類型的安全問題)。
編輯:我對誤解你想要進入的方向表示歉意。我認爲簡單地轉換表達方式仍然是你的最佳途徑。它使您能夠根據需要處理轉換。 Marc Gravell's answer here是我見過的最緊湊和最清晰的方式。
爲了這一點,我寫了ExpressionVisitor超載VisitLambda和VisitParameter
這就是:
public class ConverterExpressionVisitor<TDest> : ExpressionVisitor
{
protected override Expression VisitLambda<T>(Expression<T> node)
{
var readOnlyCollection = node.Parameters.Select(a => Expression.Parameter(typeof(TDest), a.Name));
return Expression.Lambda(node.Body, node.Name, readOnlyCollection);
}
protected override Expression VisitParameter(ParameterExpression node)
{
return Expression.Parameter(typeof(TDest), node.Name);
}
}
public class A { public string S { get; set; } }
public class B : A { }
static void Main(string[] args)
{
Expression<Func<A, bool>> ExpForA = a => a.S.StartsWith("Foo");
Console.WriteLine(ExpForA); // a => a.S.StartsWith("Foo");
var converter = new ConverterExpressionVisitor<B>();
Expression<Func<B, bool>> ExpForB = (Expression<Func<B, bool>>)converter.Visit(ExpForA);
Console.WriteLine(ExpForB); // a => a.S.StartsWith("Foo"); - same as for A but for B
Console.ReadLine();
}
這太簡單了,謝謝! – pil0t 2012-08-22 07:14:37
這是非常好的。 – 2015-09-23 08:19:39