You are using the non-generic System.Collections.IList
together with the generic System.Collections.Generic.IEnumerable<>
, as the operands of the ??
operator. Since neither interface inherits the other, that will not work.
I suggest you do:
foreach (DrawingPoint drawingPoint in e.OldItems ?? Array.Empty<DrawingPoint>())
...
instead. This will work because any Array
is a non-generic IList
. (One-dimensional zero-indexed arrays are also generic IList<>
at the same time, by the way.)
The "common" type picked by ??
will be non-generic IList
in that case.
Array.Empty<T>()
has the advantage of reusing the same instance every time it is called with the same type parameter T
.
In general, I would avoid using non-generic IList
. Note that there exists an invisible explicit cast from object
to DrawingPoint
in the foreach
code you have (also with my suggestion above). That is something that will only be checked at run-time. If the IList
contains other objects than DrawingPoint
, it blows up with an exception. If you can use the more type-safe IList<>
, then the types can be checked already as you type your code.
I see a comment by ckuri (to another answer in the thread) that already suggested Array.Empty<>
. Since you do not have the relevant .NET version (according to comments there), maybe you should just do something like:
public static class EmptyArray<TElement>
{
public static readonly TElement[] Value = new TElement[] { };
}
or just:
public static class EmptyArray<TElement>
{
public static readonly TElement[] Value = { };
}
then:
foreach (DrawingPoint drawingPoint in e.OldItems ?? EmptyArray<DrawingPoint>.Value)
...
Just like the Array.Empty<>()
method, this will ensure we reuse the same empty array each time.
One final suggesting is forcing the IList
to be generic by the Cast<>()
extension method; then you can use Enumerable.Empty<>()
:
foreach (var drawingPoint in
e.OldItems?.Cast<DrawingPoint> ?? Enumerable.Empty<DrawingPoint>()
)
...
Note the use of ?.
and the fact that we can use var
now.