Ошибка приведения: IList <T>в пользовательский класс, реализующий ICollection <T> - PullRequest
3 голосов
/ 09 сентября 2010

Это моя пользовательская декларация коллекции.

public interface IMenuCollection<T> : ICollection<T>
public class HTMLMenuCollection: IMenuCollection<HTMLMenu>

Я пытаюсь привести ее из другой коллекции IList<T>.

IList<HTMLMenu> htmlMenuList = new List<HTMLMenu>();
...
HTMLMenuCollection tempColl = (HTMLMenuCollection)htmlMenuList;

Я не знаю, почему это победилот работа.Если я приведу IList<T> к ICollection<T>, все будет работать нормально, но при этом я получу недопустимое исключение приведения.Что я делаю не так?

Ответы [ 5 ]

5 голосов
/ 09 сентября 2010

Думайте о наследовании как о «есть» отношениях.

Тогда вы можете думать об этом, потому что HTMLMenuCollection - это List<HTMLMenu>, но не каждый List<HTMLMenu> - это HTMLMenuCollection (поскольку List<HTMLMenu> не наследуется от HTMLMenuCollection).

Причина, по которой вы можете преобразовать Список из IList в ICollection:

public class List<T> : IList<T>, ICollection<T> // and more

и

public interface IList<T> : ICollection<T> // and more
5 голосов
/ 09 сентября 2010

Он не разыгрывается, потому что List<HTMLMenu> просто не реализует HTMLMenuCollection, даже если он имеет такой же набор членов.

0 голосов
/ 23 января 2015

Другим обходным решением может быть использование метода AddRange(IEnumerable<HtmlMenu>), который предоставляется HtmlMenuCollection посредством реализации ICollection<HtmlMenu>.

0 голосов
/ 09 сентября 2010

Приведение в .net выполняется во время выполнения, поэтому вы должны смотреть на тип экземпляра, а не на объявленный тип переменной. Тип экземпляра htmlMenuList: List<HTMLMenu>, который не может быть приведен к HTMLMenuCollection, поскольку List<HtmlMenu> нет и не наследуется от HtmlMenuCollection.

0 голосов
/ 09 сентября 2010

HTMLMenuCollection не реализует IList. Актерский состав ICollection работает потому, что оба они наследуются от ICollection.

Кроме того, вы передаете с List на HTMLMenuCollection, что не сработает, поскольку HTMLMenuCollection не наследуется от List, и, несмотря на это, преобразование с повышением частоты не может работать, поскольку компилятор будет HTMLMenuCollection, чтобы иметь больше данных (даже если их нет), чем List.

Возможно, было бы более полезно передать список в конструктор, а внутренние реализации методов ICollection просто передать в любое поле контейнера, внутри которого вы храните его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...