Ковариация с интерфейсом - перечисление интерфейса - PullRequest
1 голос
/ 12 марта 2012

У меня есть такой класс:

public partial class GmxGlobalList : DynamicBindingListBase<GmxGlobal> 

Где DynamicBindingListBase реализует Collection<T>, который простирается от IEnumerable<T> - в данном случае IEnumerable<GmxGlobal>.

Класс GmxGlobal определяется как

public partial class GmxGlobal : IGmxGlobal 

Я хочу сейчас объявить GmxGlobalList как

public partial class GmxGlobalList : DynamicBindingListBase<GmxGlobal>, IEnumerable<IGmxGlobal>

Но это не работает, потому что я должен объявить метод IEnumerator<IGmxGlobal> GetEnumerator() - но он уже реализован с Collection<T> - но не с IGmxGlobal, а с GmxGlobal. Я бы спросил вас, почему я должен реализовать IEnumerator<IGmxGlobal> GetEnumerator()? - Что мне делать, чтобы я мог объявить, что GmxGlobalList - это IEnumerable или ICollection или IList из IGmxGlobal (или что-то другое, где можно перечислить IGmxGlobal).

Ответы [ 2 ]

1 голос
/ 12 марта 2012

Поскольку DynamicBindingListBase<T> реализует IEnumerable<T>, а GmxGlobalList наследует от DynamicBindingListBase<GmxGlobal> и реализует IEnumerable<IGmxGlobal>.
GmxGlobalList реализует как IEnumerable<GmxGlobal>, так и IEnumerable<IGmxGlobal>.

Я собираюсь предположить, что DynamicBindingListBase<T> уже имеет конкретную реализацию IEnumerable<T>. Эта реализация не будет работать как IEnumerable<IGmxGlobal>, поскольку IEnumerable<IGmxGlobal> имеет более широкий охват, чем IEnumerable<GmxGlobal>.

Если бы у вас было просто следующее:

GmxGlobalList : DynamicBindingListBase<GmxGlobal>

Поскольку IEnumerable является ко-вариантом, вы уже можете использовать GmxGlobalList как IEnumerable<IGmxGlobal>. Как это:

IEnumerable<IGmxGlobal> foo = new GmxGlobalList();

Если вам действительно нужно реализовать IEnumerable<IGmxGlobal>, вы можете написать детали реализации, чтобы обернуть вокруг DynamicBindingListBase<GmxGlobal>.

public IEnumerator<IGmxGlobal> GetEnumerator()
{
    return (base as IEnumerator<GmxGlobal>).GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}
0 голосов
/ 12 марта 2012

Это работает?

IEnumerable<IGmxGlobal> e = (IEnumerable<GmxGlobal>)instanceOfGmxGlobalList;
...