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.