为什么表达式树中需要转换

2024-02-04

From 这个问题 https://stackoverflow.com/questions/5067120/expression-trees-and-nullable-types我5分钟前问过,很明显下面的代码抛出了一个异常,指出

未处理的异常: System.InvalidOperationException: 二元运算符 Equal 未定义 对于类型 'System.Nullable`1[System.Int32]' 和 '系统.Int32'。

Code

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确实有效

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

问题是,why is Expression.Constant无法隐式转换int? to ... int?


表达式树在正常源代码的较低级别上工作 - 您可以将它们视为在output编译器而不是input。因此,虽然存在隐式转换int to int?在 C# 中,每当编译器将其用于普通方法时,该转换都必须以 IL 表示...因此它也必须以表达式树表示形式出现。

话虽如此,鉴于您正在尝试使用int(即ItemTypeValue.Value) 作为一个值int?常量,并且我们不知道该类型是什么ItemType财产是要么。

一个短暂的但是complete您期望的工作示例确实会有帮助。

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

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

那么这就叫Expression.Constant(object) http://msdn.microsoft.com/en-us/library/bb349084.aspx其中框的值foo。在那时候,Expression.Constant不能说它原来是一个int?,因为它现在是盒装的int。这就是 .NET 拳击的工作方式:

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

那个超载的Expression.Constant根据给定的值确定表达式的整体类型 - 因此它创建一个int表达式,而你确实想要一个int?表达。

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

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

从您的问题中尚不完全清楚哪些代码有效,哪些无效,但希望这会有所帮助......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么表达式树中需要转换 的相关文章

随机推荐