首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果一个操作数为可空类型,另一个操作数为不可空类型,则Expression.GreaterThan将失败。

如果一个操作数为可空类型,另一个操作数为不可空类型,则Expression.GreaterThan将失败。
EN

Stack Overflow用户
提问于 2010-01-18 18:25:46
回答 6查看 18.7K关注 0票数 35

我正在创建一些动态linq,并遇到以下问题:

二进制运算符GreaterThanOrEqual未为“System.Nullable`1System.DateTime”和“System.DateTime”类型定义

我明白为什么,因为我的字段类型是可空的,并且本质上是传入DateTime.Now的。

所以在试图解决这个问题时,我试过

代码语言:javascript
复制
System.Nullable<DateTime> now;
now = DateTime.Now;

但是结果类型是一个非空对象,因此仍然给出了上面的例外情况。

有什么建议吗!

更新:为了得到更多的澄清,现在变量在设置为非空类型时变为非空类型,而不是保留为可空的DateTime,因此匹配抛出一个异常。

Update:实际代码可以在CodePlex项目中看到:

http://webquarters.codeplex.com/SourceControl/changeset/view/36529#574700

违规线是145。

代码语言:javascript
复制
fExp = Expression.GreaterThanOrEqual(fExpLeft, fExpRight);
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-01-18 20:07:47

这里的问题是,当给定两个不匹配的空值参数时,表达式库将抛出一个异常。这里有一个简单的复制:

代码语言:javascript
复制
Expression<Func<DateTime?>> ex1 = ()=>DateTime.Now;
Expression<Func<DateTime>> ex2 = ()=>DateTime.Now;
var ex3 = Expression.GreaterThan(ex1.Body, ex2.Body);

我不清楚这是否是一个bug;规则of C#要求在这种情况下,非空操作数被转换为可空操作数,并且使用了比较的可解除为空的形式。然而,表达式树库不需要来遵循C#的规则,因为表达式树库当然可以用来表示C#表达式、Python表达式、JScript表达式、VB表达式等;它不可能遵循每种语言的所有规则。

但是无论如何,这看起来可能是个bug,所以我会把它提交给表达式树团队,看看他们怎么说。同时,您可以轻松地通过定义自己的助手方法来解决这个问题,该方法可以修复操作数。一个简短的草图是:

代码语言:javascript
复制
    static Expression MyGreaterThan(Expression e1, Expression e2)
    {
        if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
            e2 = Expression.Convert(e2, e1.Type);
        else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
            e1 = Expression.Convert(e1, e2.Type);
        return Expression.GreaterThan(e1, e2);
    }
    static bool IsNullableType(Type t)
    {
        return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
    }

但是,注意到,这并不能检查e1和e2的类型是否仅在可空性方面有所不同;如果传入可空int和非空双表达式,则会发生不好的事情。,我将其作为一项练习,以实现更好的逻辑,以检查这两个表达式的类型是否只有空性不同。

票数 72
EN

Stack Overflow用户

发布于 2010-01-18 18:28:53

我不清楚您的代码到底是什么,但是要获得非空版本的Nullable,请调用它的.Value成员。

票数 2
EN

Stack Overflow用户

发布于 2010-01-18 18:37:31

无论您的比较是什么,请按以下方式更改比较:

代码语言:javascript
复制
(nullableDT >= DT)

代码语言:javascript
复制
(nullableDT != null && nullableDT.Value >= DT)

编辑:

根据您的注释,编写一个包含2个对象的函数,在函数中检查它们是否为空类型,并检查null,然后比较值。此函数可能使用类似于^的代码。

不过,这听起来好像你有一个更大的潜在问题。要么你得到了不正确的数据。其他地方的代码正在返回不应该是的数据,而不是代码中的问题,而是逻辑中的问题),或者您认为可以比较这些对象的假设是无效的。这又一次是一个逻辑错误。

我想你应该退后一小会儿。如果你张贴更多的代码,我们可能会帮助你更多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2088231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档