Как конвертировать выражение> к выражению> - PullRequest
3 голосов
/ 06 сентября 2010

Следующее работает, но мой Body.NodeType меняется на Преобразовать вместо MemberAccess , что является проблемой при получении ModelMetadata.FromLambdaExpression:

private Expression<Func<TModel, TNewProperty>> ConvertExpression<TProperty, TNewProperty>(Expression<Func<TModel, TProperty>> expression)
{
    Exression converted = Expression.Convert(expression.Body, typeof(TNewProperty));
    var result =  Expression.Lambda<Func<TModel, TNewProperty>>(converted,    expression.Parameters);
    return result;
}

В контексте ASP.NET MVC 2.0 у меня есть собственный редактор для:

public MvcHtmlString EditorFor<TProperty>(Expression<Func<TModel, TProperty>> expression)

EditorFor затем делегирует вызов внутренне, на основе метаданных, определенным методам, например:

public DecimalTextBox DecimalTextBoxFor(Expression<Func<TModel, decimal?>> expression)

DecimalTextBox имеет свойство Value типа decimal ?, поэтому я хочу установить его:

decimalTextBox.Value(expression.Compile()(ViewData.Model));

Вызов из EditorFor для DecimalTextboxFor не компилируется, потому что типы не совпадают, и поэтому мне нужно преобразование.

Выше кода выполняется преобразование, но поскольку изменяется Expression.Body.NodeType, ModelMetadata.FromLambdaExpression не работает, потому что тип выражения должен быть ArrayIndex, Call, MemberAccess или Parameter. Преобразование не принято.

Мой обходной путь изменяет DecimalTextBoxFor на:

public DecimalTextBox DecimalTextBoxFor(Expression<Func<TModel, TProperty>> expression)

и преобразовать значение внутри:

decimalTextBox.Value((decimal?) Convert.ChangeType(expression.Compile()(ViewData.Model), typeof(decimal?)));

Другое преобразование, которое частично работает:

private Expression<Func<TModel, TNewProperty>> ConvertExpression<TProperty, TNewProperty>(Expression<Func<TModel, TProperty>> expression)
{
     Expression<Func<TModel, TNewProperty>> convertedExpression = expression as Expression<Func<TModel, TNewProperty>>;
}

Но преобразование различных типов значений (например, одинарных в двойные), конечно, не работает.

Я надеялся преобразовать само выражение ...

1 Ответ

1 голос
/ 06 сентября 2010

К сожалению, это невозможно без изменения NodeType Body.Выражение Convert является отдельным типом выражения и представляет фактическую операцию.Чтобы достичь того, чего вы пытаетесь достичь, эта операция должна быть «первой» операцией, то есть самым верхним узлом в дереве выражений.

Я мог бы предложить обходной путь, если вы объясните почему вы думаете, что вам нужно NodeType, чтобы остаться прежним.Семантически это не имеет смысла: Body старого выражения представляет собой конкретную операцию, а ваша новая Body представляет другую операцию (а именно, исходную операцию, за которой следует Convert).Вы не можете ожидать, что он будет представлять старую операцию и все же вернуть результат новой операции.

...