1

我有一个具有以下结构的表达式。我从 a 得到它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);
    }
}

*更多信息ExpressionRewriterhttps ://stackoverflow.com/a/1720642/1587864

我想继续使用IEnumerable,我真的需要Array在另一个表达式中使用。在合并它们之前,我有什么办法可以以某种方式对这些表达式进行转换?

谢谢

4

2 回答 2

1

您可以使用 LINQEnumerable.ToArray作为中间表达式。

Expression<Func<IEnumerable<TModel>, TModel[]>> toArray = x => x.ToArray();
于 2013-04-03T15:23:14.800 回答
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();
于 2013-04-03T15:31:24.510 回答