我怎樣才能讓一個通用的輔助方法,通過函數求所使用的類型從一種類型轉換爲另一種表達轉換表達<Func鍵<FromType>>以表達<Func<ToType>>
內我有一個Expression<Func<IEmployee, bool>>
,我想轉換它到
Expression<Func<Employee, bool>>.
第二個類型總是實現第一個類型。一個通用的解決方案是我想要實現的。
編輯
我編輯了這個問題更清楚。
我怎樣才能讓一個通用的輔助方法,通過函數求所使用的類型從一種類型轉換爲另一種表達轉換表達<Func鍵<FromType>>以表達<Func<ToType>>
內我有一個Expression<Func<IEmployee, bool>>
,我想轉換它到
Expression<Func<Employee, bool>>.
第二個類型總是實現第一個類型。一個通用的解決方案是我想要實現的。
編輯
我編輯了這個問題更清楚。
嗯,你可以創建一個蒙上表達式,然後其參數轉發給原始表達式:
Expression<Func<IEmployee, bool>> source = ...
var param = Expression.Parameter(typeof(Employee));
// Types the argument as the type expected by the source expression
// and then forwards it...
var invocationExpr = Expression.Invoke
(source, Expression.TypeAs(param, typeof(IEmployee)));
var result = Expression.Lambda<Func<Employee, bool>>(invocationExpr, param);
如果供應商不支持調用表達式,你可能會需要一個更加 複雜的解決方案替換源表達式中的參數。
編輯:好吧,既然你說你的提供者不喜歡結果表達式,這裏是一個替代的例子。這是一個真的粗略的參數替代物應該看起來像(我現在只是寫了一個樣本),但它應該適用於您的目的。
public static class ParameterReplacer
{
// Produces an expression identical to 'expression'
// except with 'source' parameter replaced with 'target' parameter.
public static Expression<TOutput> Replace<TInput, TOutput>
(Expression<TInput> expression,
ParameterExpression source,
ParameterExpression target)
{
return new ParameterReplacerVisitor<TOutput>(source, target)
.VisitAndConvert(expression);
}
private class ParameterReplacerVisitor<TOutput> : ExpressionVisitor
{
private ParameterExpression _source;
private ParameterExpression _target;
public ParameterReplacerVisitor
(ParameterExpression source, ParameterExpression target)
{
_source = source;
_target = target;
}
internal Expression<TOutput> VisitAndConvert<T>(Expression<T> root)
{
return (Expression<TOutput>)VisitLambda(root);
}
protected override Expression VisitLambda<T>(Expression<T> node)
{
// Leave all parameters alone except the one we want to replace.
var parameters = node.Parameters.Select
(p => p == _source ? _target : p);
return Expression.Lambda<TOutput>(Visit(node.Body), parameters);
}
protected override Expression VisitParameter(ParameterExpression node)
{
// Replace the source with the target, visit other params as usual.
return node == _source ? _target : base.VisitParameter(node);
}
}
}
,然後用它作爲:
Expression<Func<IEmployee, bool>> expression = ...
var result = ParameterReplacer.Replace
<Func<IEmployee, bool>, Func<Employee, bool>>
(expression,
expression.Parameters.Single(),
Expression.Parameter(typeof(Employee));
我正在使用Teleriks OpenAccess,它似乎並不喜歡產生的表達式。 – David
好的,繼續。會給你一個參數替代品的樣本。 – Ani
David做了那個工作嗎? – Ani