Вы используете неуниверсальный System.Collections.IList
вместе с универсальным System.Collections.Generic.IEnumerable<>
в качестве операндов оператора ??
.Поскольку ни один интерфейс не наследует другой, это не сработает.
Я предлагаю вам сделать:
foreach (DrawingPoint drawingPoint in e.OldItems ?? Array.Empty<DrawingPoint>())
...
.Это будет работать, потому что любой Array
не является общим IList
.(Между прочим, одномерные массивы с нулевым индексом также универсальные IList<>
в то же время.)
«Общий» тип, выбранный ??
, не будетуниверсальный IList
в этом случае.
Array.Empty<T>()
имеет преимущество в повторном использовании одного и того же экземпляра каждый раз, когда он вызывается с одним и тем же параметром типа T
.
В общем, я быИзбегайте использования не универсальных IList
.Обратите внимание, что существует невидимое явное приведение от object
до DrawingPoint
в коде foreach
, который у вас есть (также с моим предложением выше).Это то, что будет проверяться только во время выполнения.Если IList
содержит другие объекты, кроме DrawingPoint
, он взрывается с исключением.Если вы можете использовать более безопасный тип IList<>
, то типы можно проверять уже при вводе кода.
Я вижу комментарий ckuri (к другому ответу в теме), чтоуже предложено Array.Empty<>
.Поскольку у вас нет соответствующей версии .NET (согласно комментариям там), возможно, вам следует просто сделать что-то вроде:
public static class EmptyArray<TElement>
{
public static readonly TElement[] Value = new TElement[] { };
}
или просто:
public static class EmptyArray<TElement>
{
public static readonly TElement[] Value = { };
}
затем:
foreach (DrawingPoint drawingPoint in e.OldItems ?? EmptyArray<DrawingPoint>.Value)
...
Так же, как и метод Array.Empty<>()
, это обеспечит повторное использование одного и того же пустого массива каждый раз.
Последнее предложение - принудительное использование IList
в качестве универсальногоCast<>()
метод расширения;тогда вы можете использовать Enumerable.Empty<>()
:
foreach (var drawingPoint in
e.OldItems?.Cast<DrawingPoint> ?? Enumerable.Empty<DrawingPoint>()
)
...
Обратите внимание на использование ?.
и тот факт, что мы можем использовать var
сейчас.