我正在创建一些动态linq并遇到以下异常问题:
没有为类型'System.Nullable`1 [System.DateTime]'和'System.DateTime'定义二元运算符GreaterThanOrEqual
我明白了,因为我的字段类型是可以为空的,而且我实际上是在DateTime.Now中传递的.
所以在试图解决这个问题时我已经尝试过了
System.Nullable<DateTime> now;
now = DateTime.Now;
Run Code Online (Sandbox Code Playgroud)
但结果类型是一个不可为空的对象,因此仍然给我上述异常.
有什么建议?!
更新:为了进一步说明,now变量在设置时变为非可空类型,而不是保持为可空的DateTime,因此匹配会引发异常
更新:可以在CodePlex项目中看到实际代码:
http://webquarters.codeplex.com/SourceControl/changeset/view/36529#574700
违规线约为145
fExp = Expression.GreaterThanOrEqual(fExpLeft, fExpRight);
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 57
这里的问题是,当给出两个不匹配的可为空性的参数时,表达式库会抛出异常.这是一个简单的复制品:
Expression<Func<DateTime?>> ex1 = ()=>DateTime.Now;
Expression<Func<DateTime>> ex2 = ()=>DateTime.Now;
var ex3 = Expression.GreaterThan(ex1.Body, ex2.Body);
Run Code Online (Sandbox Code Playgroud)
我不清楚这是不是一个错误; C#的规则要求在这种情况下,非可空操作数转换为可空,并使用提升到可空的比较形式. 但是,表达式树库不需要遵循C#的规则,因为表达式树库当然可以用来表示C#表达式,Python表达式,JScript表达式,VB表达式等等; 它不可能遵循所有可能语言的所有规则.
但无论如何,这看起来可能是一个bug,所以我会将它提交给表达式树队,看看他们说了什么.同时,您可以通过定义自己的辅助方法来轻松解决操作,修复操作数.快速草图将是:
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<>);
}
Run Code Online (Sandbox Code Playgroud)
但是,请注意,这并不会检查e1和e2的类型是否仅在可空性方面有所不同; 如果你传入一个可以为空的int和一个不可为空的双重表达式,就会发生不好的事情.我把它留作练习来实现更好的逻辑,检查这两个表达式是否只有可空性的类型.
归档时间: |
|
查看次数: |
15254 次 |
最近记录: |