I regularly find myself coding things like
int? min = someQueryable
.Where(x => someCondition)
.Select(x => (int?)x.someNonNullableIntProperty)
.Min();
It allows me to get null instead of "System.ArgumentNullException: value cannot be null" when nothing matches the condition. (And I do not want to get 0
instead of null
.)
I would like to avoid the cast. Is there any other way I have missed?
The hard part is, it should be of sufficiently common use to be natively understood (or ignored) by linq providers. (linq-to-entities and linq-to-nhibernate for my specific needs.)
Otherwise I would have to add some custom AsNullable
extensions to linq-to-nh provider (which requires some work), and I do not know if EF (6) allows to do this.
Why do I wish avoiding cast? Casting may go unnoticed during refactoring, and then may cause bugs. And most of the cast I see in code are due to careless developers, not trying to memorize they can have the non-null value from .Value
on nullable types, by example. (There is also the ternary case like someCondition ? someIntProperty : (int?)null
but the "Elvis" operator ?.
will probably allow to avoid most of them ; and we can also write default(int?)
, althougth it is a bit lengthy. ?.
could maybe even be used for my example query, but it would not be a general solution.)
Trying new Nullable<int>(x.someNonNullableIntProperty)
as suggested here fails with a NotSupportedException
(with NH, not tested with EF). Anyway, it would not suit me either. In case of some later type change of the property, it may go unnoticed too due to implicit conversion. (And trying new Nullable(x.someNonNullableIntProperty)
does not compile, generic type argument inferring does not work well with constructors.)
Trying x.someNonNullableIntProperty as int?
(which is still a cast, but less tolerant about types mismatch in this case, see this here) fails with an ArgumentException
(NH tested again, Expression of type 'System.Int32' cannot be used as a 'System.Nullable`1[System.Int32]' return type (translated)).