为什么转换必要的表达式树 [英] Why is a conversion necessary in Expression Trees

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

问题描述

问题我问5分钟前,很显然,下面的代码抛出一个异常,指出

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

未处理的异常:
System.InvalidOperationException:在
二元运算符不等于定义
的各类
'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?

推荐答案

表达式树在较低水平,以正常的源代码的工作 - 你可以把它们想象成在一级开展工作的的输出的编译器,而不是的输入的。因此,尽管有来自 INT 在C#中的隐式转换为 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);



然后调用的 Expression.Constant(对象) 这盒富 。在这一点上, Expression.Constant 不能告诉你它原本是一个 INT?,因为它现在是一个盒装 INT 。这只是顺便.NET拳作品:

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.

为了妥善维护类型的信息,你必须使用它允许你指定类型的过载:

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?));



这仍然没有完全从你的问题清楚哪些代码的作品,哪些没有,但希望那LL帮助...

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

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

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