为什么在表达式树中需要进行转换 [英] Why is a conversion necessary in Expression Trees

查看:128
本文介绍了为什么在表达式树中需要进行转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题我5分钟前问过,很明显,以下代码抛出异常,表示

From this question I asked 5 minutes ago, it's clear that the following code throws an exception, stating that


未处理的异常:
System.InvalidOperationException:
二进制运算符Equal未定义

'System.Nullable`1 [System.Int32]'和
'System.Int32'

Unhandled Exception: System.InvalidOperationException: The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'.

代码

public static void GetResultCollection<T>() {
        AccrualTrackingEntities db = new AccrualTrackingEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

        int? ItemTypeValue = 1;

        var param = Expression.Parameter(typeof(T));

        var lambda = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(param, "ProcInstId"),
                Expression.Constant(ItemTypeValue)),
            param);

        var list = result.Where(lambda).ToList();
    }

然而,这个代码与 Expression.Constant 确实工作

This code, however, with the type explicitly listed in Expression.Constant does work

class Program {
    public static void GetResultCollection<T>() {
        AccrualTrackingEntities db = new AccrualTrackingEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

        int? ItemTypeValue = 1;

        var param = Expression.Parameter(typeof(T));

        var lambda = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(param, "ProcInstId"),
                Expression.Constant(ItemTypeValue, typeof(int?))),
            param);

        var list = result.Where(lambda).ToList();
    }

问题是,为什么 Expression.Constant 无法从 int 隐式转换为... int?

The question is, why is Expression.Constant not able to convert implicitly from int? to ... int?

推荐答案

表达式树在较低级别工作到正常的源代码 - 你可以将它们认为是在层级上工作的输出,而不是输入。所以在C#中有一个从 int int 的隐式转换时,必须在IL中表示转换编译器将其用于正常的方法...所以它也必须存在于表达式树表示中。

Expression trees work at a lower level to normal source code - you can think of them as working at the level of the output of the compiler rather than the input. So while there's an implicit conversion from int to int? in C#, that conversion has to be represented in IL whenever the compiler uses it for a normal method... so it also has to be present in an expression tree representation.

说完了,你的例子有点不清楚,因为您正在尝试使用 int (即 ItemTypeValue.Value )作为 int?常量,我们不知道什么类型的 ItemType 属性是。

Having said that, your example is somewhat unclear, given that you're trying to use an int (namely ItemTypeValue.Value) as a value for an int? constant, and we don't know what the type of the ItemType property is either.

您希望工作的简短但完整的示例真的有帮助。

A short but complete example of what you'd expect to work would really help.

编辑:好的,我以为我现在和你在一起问题是如果您使用

Okay, I think I'm with you now. The problem is that if you use

int? foo = 1;
Expression.Constant(foo);

然后调用表达式(对象) 其中包含 foo 。在这一点上, Expression.Constant 不能说它原来是一个 int?,因为它现在是一个盒装 INT 。这就是.NET Boxing的工作原理:

then that calls Expression.Constant(object) which boxes the value of foo. At that point, Expression.Constant can't tell it was originally an int?, because it's now a boxed int. That's just the way .NET boxing works:

int? foo = 1;
object o = foo;
Console.WriteLine(o.GetType()); // Prints System.Int32

Expression.Constant 从给定的值确定表达式的总体类型,所以它创建一个 int 表达式,而你真的想要一个 int ?表达式。

That overload of Expression.Constant determines the overall type of the expression from the value that it's given - so it creates an int expression, whereas you really want an int? expression.

为了正确维护类型信息,您必须使用允许您指定类型的重载: p>

In order to maintain the type information properly, you have to use the overload which allows you to specify the type:

int? foo = 1;
Expression.Constant(foo, typeof(int?));

您的问题仍然不完全清楚哪些代码有效,哪些代码不起作用,但希望帮助...

It's still not entirely clear from your question which code works and which doesn't, but hopefully that'll help...

这篇关于为什么在表达式树中需要进行转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆