如何将表达式>转换为到表达式>

发布于 2024-09-18 14:38:58 字数 2018 浏览 2 评论 0 原文

以下内容有效,但我的 Body.NodeType 更改为 Convert,而不是 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 的上下文中,我有自己的 EditorFor:

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

EditorFor 然后根据元数据在内部将调用委托给特定方法,例如:

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

DecimalTextBox 有一个十进制类型的 Value 属性?,所以我想设置它:

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>>;
}

但是转换不同的值类型(例如单精度到双精度)当然不起作用。

我希望转换表达式本身......

The following is working, but my Body.NodeType changes to Convert, instead of MemberAccess which is a problem when getting 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;
}

In the context of a ASP.NET MVC 2.0, I have my own EditorFor:

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

The EditorFor then delegates the call internally, based on metadata, to specific methods, ex:

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

The DecimalTextBox has a Value property of type decimal?, so I want to set it:

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

Call form the EditorFor to the DecimalTextboxFor doesn't compile bacause the types don't match, and that's why I need the conversion.

Above code, does the conversion, but because the Expression.Body.NodeType is changed, the
ModelMetadata.FromLambdaExpression doesn't work, because the expression type needs to be an ArrayIndex, Call, MemberAccess or Parameter. Convert is not accepted.

My workaround is changing the DecimalTextBoxFor into:

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

and convert the value inside there:

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

An other conversion that does partially work is:

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

But converting different value types (ex. single to double) doesn't work of course.

I was hoping to convert the Expression itself...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红墙和绿瓦 2024-09-25 14:38:58

不幸的是,如果不更改 BodyNodeType,这是不可能的。 Convert 表达式是一种单独的表达式类型,代表实际操作。为了实现您想要实现的目标,该操作必须是“第一个”操作,即表达式树中的最顶层节点。

如果您解释为什么您认为需要 NodeType 保持不变,我也许可以提供解决方法。从语义上讲,这没有意义:旧表达式的 Body 表示特定操作,而新的 Body 表示不同操作(即,原始操作后跟Convert)。您不能期望它代表旧操作但返回新操作的结果。

Unfortunately, this is not possible without changing the NodeType of the Body. The Convert expression is a separate expression type and represents an actual operation. In order to achieve what you are trying to achieve, that operation has to be the “first” operation, i.e. the topmost node in the expression tree.

I might be able to provide a workaround if you explain why you think you need the NodeType to remain the same. Semantically this doesn’t make sense: The Body of the old expression represents a specific operation, and your new Body represents a different operation (namely, the original operation followed by Convert). You can’t expect it to represent the old operation and yet return the result of the new operation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文