![](/img/trans.png)
[英]Howto convert Expression Func<T, object[]> to Func<T, object>
[英]Convert Expression<Func<T, object>> to Expression<Func<object>>
如何轉換: Expression<Func<T, object>>
到Expression<Func<object>>
?
例如:
public class Entity
{
public virtual long Id { get; set; }
}
起源:
Expression<Func<Entity, object>> origin = x => x.Id;
目的地:
Entity alias = null;
Expression<Func<object>> destination = () => alias.Id;
實際上,我正在嘗試為Nhibernate創建一個自定義的可緩存ResultTransformer。 有一個public QueryOverProjectionBuilder<T> WithAlias(Expression<Func<object>> alias);
但是在我的類中,對於每個特定實體,我想使用更特定的選擇器,例如Expression<Func<T, object>>
您有兩種選擇:
選項1與Expression.Invoke
一樣簡單,但可能與LINQ等庫不兼容。 選項2最好使用表達式訪問者來完成:
private class ExchangeParametersVisitor : ExpressionVisitor
{
public ParameterExpression Parameter { get; set; }
public Expression Value { get; set; }
protected override Expression VisitParameter(ParameterExpression node)
{
if (node == Parameter)
{
return Value;
}
return node;
}
}
您需要做的是將訪問者應用於lambda表達式的主體,並使用它來創建一個新的lambda表達式,該表達式包含與之前相同的所有參數,但您替換的參數除外。
這就是Expression.Invoke
目的。
創建一個新的lambda表達式,然后對原始表達式使用Expression.Invoke
組成兩個表達式。
樣品:
Expression<Func<string, int>> inner = x => int.Parse(x);
var outer = Expression.Lambda<Func<int>>
(Expression.Invoke(inner, Expression.Constant("123")));
outer.Compile()().Dump(); // 123
遺憾的是,某些表達式解析器無法正確處理Invoke
他們認為它是方法的調用,並拒絕它。 在這種情況下,您需要內聯表達式。 這意味着訪問整個內部表達式,並在更好的情況下用變量替換ParameterExpression
,或者如果解析器也不支持,則在所有位置插入參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.