c# - Shouldn't calling Enumerable.AsEnumerable() on null variable throw an exception?
问题描述
I had a piece of code that used this expression - someCollection.AsEnumerable()
. Later on I realized that, in some cases the someCollection
was set to null
. However, I never got any exception from this code. I even ran it through the debugger. If I remember correctly, the expression someCollection.AsEnumerable()
evaluated to null
if someCollection
was set to null
.
Shouldn't calling someCollection.AsEnumerable()
throw an exception if someCollection
was set to null
? Am I missing something?
解决方案
AsEnumerable
is an extension method. It's defined like this:
public static class Enumerable
{
public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{
return source;
}
}
It's valid to call extension methods on null
-- writing someCollection.AsEnumerable()
is just syntactic sugar for writing Enumerable.AsEnumerable(someCollection)
. You'd be surprised if you wrote Enumerable.AsEnumerable(null)
and got a NullReferenceException
!
As you can see, there's no test for null
inside AsEnumerable
- if it's passed null
, it will just return null
.
AsEnumerable
could have been written to contain an explicit test for null
-- if (source == null) throw new ArgumentNullException(nameof(source));
(which would throw an ArgumentNullException
, rather than a NullReferenceException
).
But, from MSDN:
The
AsEnumerable<TSource>(IEnumerable<TSource>)
method has no effect other than to change the compile-time type of source from a type that implementsIEnumerable<T>
toIEnumerable<T>
itself.
If you have a null
typed as an IQueryable<T>
, I think it's perfectly valid for this method to turn it into a null
typed as an IEnumerable<T>
. null
is after all a perfectly valid IEnumerable<T>
and IQueryable<T>
.
Another way of looking at this is, what's to be gained from throwing an exception if the source
is null
? The method can work perfectly fine it it's passed null
, and that might be useful to someone.