Как я бросаю Список <T> эффективно?

Ну, надеюсь, у тебя есть ответ. Если нет, вы можете попробовать посмотреть в режиме отладки. подкласс B имеет доступ как к intVal. Они не являются полиморфными, поэтому они не переоцениваются.

Если вы используете ссылку B, вы получите intVal B. Если вы используете ссылку A, вы получите intVal. Это так просто.

23
задан George Stocker 2 February 2009 в 21:06
поделиться

7 ответов

Оба.OfType< T> и.Cast< T> возвратит список T, но значение этих двух методов отличается.

список. Фильтры OfType исходный список и возвраты все объекты, которые имеют тип T и пропускают тех, которые не имеют того типа.

список. Бросок броски все объекты в исходном списке к типу T, и выдают исключение для объектов, которые не могут быть брошены к тому типу.

В Вашем случае оба дали бы тот же результат, но использующий.Cast передаст Ваше намерение намного более ясно, таким образом, я рекомендовал бы использовать это.

List<InputField> list = (from i .... select i).Cast<IDataField>.ToList();
41
ответ дан Helen Toomik 29 November 2019 в 00:59
поделиться
List<InputField> raw = (from i .... select i).ToList();
List<IDataField> result = raw.OfType<IDataField>().ToList();
11
ответ дан Amy B 29 November 2019 в 00:59
поделиться

Вы могли также использовать Список. ConvertAll.

Документация: http://msdn.microsoft.com/en-us/library/73fe8cwf.aspx

Пример:

List<IDataField> newList = oldList.ConvertAll(i => i as IDataField);
7
ответ дан CubanX 29 November 2019 в 00:59
поделиться

Так как список появляется от

List<InputField> list = (from i .... select i).ToList();

, Вы не могли только зафиксировать "выбор i" частей, чтобы вместо этого возвратить IDataField вместо этого? Что-то вроде этого:

List<InputField> list = (from i .... select (IDataField)i).ToList();

, Если это не работает, возможно, расширение "Броска" IEnumerable будет работать:

List<DataField> list2 = list.Cast<IDataField>();
5
ответ дан Arjan Einbu 29 November 2019 в 00:59
поделиться

На всякий случай: у меня есть мало опыта C#, но если эта универсальная конструкция означает то же самое, это делает в Java, затем Вы должны создавать совершенно новый Список, параметризованный супертипом. Другими словами, если каждый экземпляр Bangle является также экземпляром Akthud, он делает не , следуют, это каждый List<Bangle> также List<Akthud>.

причина этого состоит в том, что у Вас может быть две ссылки на это List<Bangle>. Если вторая ссылка бросает и затем называет его List<Akthud>, то разрешено добавить Akthud к нему - но теперь первая ссылка имеет List<Bangle>, чьи участники не весь Bangle с. Нарушение!

Однако ответ B David должен действительно сделать то, что Вы хотите, правильно, AFAICT. (Это похоже на операцию копии.)

[И если я неправильно понимаю семантику дженериков C#, я надеюсь, что кто-то исправляет меня в комментарии!]

3
ответ дан Paul Brinkley 29 November 2019 в 00:59
поделиться

ConvertAll походит на лучшее решение, так как он не зависит от библиотеки Linq и короче и более интуитивен.

, Но они оба - скорее обходные решения, чем решения. Они оба создают новый набор с теми же данными. Должна быть поддержка универсальной ковариантности в .NET, т.е. upcasting в универсальных наборах, которые позволили бы Вам делать это естественно. Например:

List<IDataField> ls = (List<IDataField>)List<InputField>

От моего поиска до сих пор, моего заключения, то, что .NET с 3,5 не поддерживает эту функцию. Следовательно мы должны закончить с обходными решениями.

Это обсуждения темы:

1
ответ дан husayt 29 November 2019 в 00:59
поделиться

Я не знаю, что прямой бросок имел бы желаемый эффект. Редкие несколько раз я сделал это, это обычно - что-то как:

List<InputField> list = .....
List<IDataField> list2 = new (List<IDataField>((IDataField[])list.ToArray()));
1
ответ дан TheSmurf 29 November 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: