我正在创建一些动态linq,但出现以下异常的问题:
我明白为什么了,因为我的字段类型可以为空,而Im实质上是传入DateTime.Now。
因此,在尝试解决此问题时,我尝试了
System.Nullable<DateTime> now;
now = DateTime.Now;
但是结果类型是不可为空的对象,因此仍然给我上述异常。
有什么建议?!
更新:为进一步说明,现在变量在设置时变为非空类型,而不是停留为可为空的DateTime,因此匹配项引发异常
更新:实际代码可以在CodePlex项目中看到:
http://webquarters.codeplex.com/SourceControl/changeset/view/36529#574700
令人讨厌的线是〜145
fExp = Expression.GreaterThanOrEqual(fExpLeft, fExpRight);
最佳答案
这里的问题是,当给定两个不匹配的可空性参数时,表达式库将引发异常。这是一个简单的复制:
Expression<Func<DateTime?>> ex1 = ()=>DateTime.Now;
Expression<Func<DateTime>> ex2 = ()=>DateTime.Now;
var ex3 = Expression.GreaterThan(ex1.Body, ex2.Body);
我不清楚这是否是错误; C#的规则要求在这种情况下,将不可为空的操作数转换为可为空的操作,并使用提升为可为空的比较形式。但是,表达式树库不需要遵循C#规则的,因为表达式树库可以用来表示C#表达式,Python表达式,JScript表达式,VB表达式等;它可能无法遵循每种可能语言的所有规则。
但是无论如何,这看起来可能是一个错误,因此我将其提交给表达式树团队,看看他们怎么说。同时,您可以通过定义自己的帮助程序方法来轻松解决此问题。一个简单的草图是:
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的类型仅在可空性方面有所不同;它仅是可空性。如果传入可为null的int和不可为null的double表达式,则会发生不良情况。 我将它留作练习,以实现更好的逻辑,该逻辑检查两个表达式的类型是否仅因可为空而不同。
关于c# - 如果一个操作数是可为空的类型,其他操作数为非可为空,则Expression.GreaterThan失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2088231/