我有一个具有以下结构的表达式。我是从Expression.ArrayIndex
得到的,所以我无法改变它:
Expression<Func<TModel[], TProperty>> expression
之后我将这个表达式与具有这种结构的父表达式结合起来:
Expression<Func<TDataSource, IEnumerable<TModel>>> dataSourceExpression
因此结果表达式应为:
Expression<Func<TDataSource, TProperty>>
请注意,在合并后我使用TDataSource
作为输入,我得到TProperty
作为结果。
但是我无法合并它们,因为TModel[]
无法转换为IEnumerable<TModel>
。
联合收割机是这样完成的:
Expression<Func<TDataSource, TProperty>> outputWithoutInline = dataSourceExpression.Combine(expression, true);
public static class ExpressionUtils
{
public static Expression<Func<T1, T3>> Combine<T1, T2, T3>(
this Expression<Func<T1, T2>> outer, Expression<Func<T2, T3>> inner, bool inline)
{
var invoke = Expression.Invoke(inner, outer.Body);
Expression body = inline ? new ExpressionRewriter().AutoInline(invoke) : invoke;
return Expression.Lambda<Func<T1, T3>>(body, outer.Parameters);
}
}
*有关ExpressionRewriter
的更多信息:https://stackoverflow.com/a/1720642/1587864
我想继续使用IEnumerable
,我真的需要在另一个表达式中使用Array
。在合并它们之前,有什么方法可以以某种方式对这些表达式进行转换吗?
谢谢
答案 0 :(得分:1)
您可以使用LINQ的Enumerable.ToArray
作为中间表达式。
Expression<Func<IEnumerable<TModel>, TModel[]>> toArray = x => x.ToArray();
答案 1 :(得分:1)
假设你有:
Expression<Func<TDataSource, IEnumerable<TModel>>> first = ...
Expression<Func<TModel[], TProperty>> second = ...
为什么你不能这样做:
Expression<Func<IEnumerable<TModel>, TModel[]>> converter = seq => seq.ToArray();
var result = first.Combine(converter, true).Combine(second, true);
如果可能的话,您可以尝试使用转换器:
Expression<Func<IEnumerable<TModel>, TModel[]>> converter
= seq => (seq as TModel[]) ?? seq.ToArray();