Коли використовувати Cast () та Oftype () в Linq


211

Мені відомо про два способи лиття типів IEnumerableз ArraylistLinq і цікаво, в яких випадках їх використовувати?

напр

IEnumerable<string> someCollection = arrayList.OfType<string>()

або

IEnumerable<string> someCollection = arrayList.Cast<string>()

Яка різниця між цими двома методами і де я повинен застосовувати кожен випадок?

Відповіді:


322

OfType- повертайте лише ті елементи, які можна безпечно передавати у тип x.
Cast- спробує передати всі елементи у тип x. якщо деякі з них не від цього типу, ви отримаєтеInvalidCastException


Наприклад, редагуйте :

object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }

1
ура за це. Спробував обидва заздалегідь, але в обох були елементи, очікуваного типу, тому я не міг бачити різниці.

6
@SLaks правильно вказує, що вам слід користуватися, Cast<T>коли ви точно знаєте, що колекція містить лише Tелементи типу . OfType<T>повільніше через isперевірку типу. Якщо колекція має тип IEnumerable<T>, Cast<T>вона просто закидає всю колекцію як IEnumerable<T>і уникатиме її перерахування; OfType<T>все одно перерахуємо. посилання: stackoverflow.com/questions/11430570 / ...
Hippy

23
Навіть у випадках, коли .Cast<string>()не кидається, коли він перераховується, це не рівнозначно .OfType<string>(). Причина в тому, що nullзначення завжди пропускаються .OfType<TResult>(). Приклад: new System.Collections.ArrayList { "abc", "def", null, "ghi", }.OfType<string>().Count()дамо лише 3; подібний вираз з .Cast<string>()оцінкою до 4.
Jeppe Stig Nielsen

1
Іншими словами, це те , як різниця між «як» і «литі» оператори
Faza

111

http://solutioising.net/2009/01/18/linq-tip-enumerable-oftype/

По суті, Cast () реалізується так:

public IEnumerable<T> Cast<T>(this IEnumerable source)
{
  foreach(object o in source)
    yield return (T) o;
}

Використання явного амплуа працює добре, але призведе до InvalidCastException, якщо виступ не вдасться. Менш ефективним, але корисним варіантом цієї ідеї є OfType ():

public IEnumerable<T> OfType<T>(this IEnumerable source)
{
  foreach(object o in source)
    if(o is T)
      yield return (T) o;
}

Повернене перерахування буде включати лише елементи, які можна безпечно передати вказаному типу.


38

Вам слід зателефонувати, Cast<string>()якщо ви знаєте, що всі елементи є strings.
Якщо деякі з них не є рядками, ви отримаєте виняток.

Вам слід зателефонувати, OfType<string>()якщо ви знаєте, що деякі елементи не є string, і ви не хочете їх.
Якщо деякі з них не є рядками, вони не будуть в новому IEnumerable<string>.


1
Ця відповідь (на даний момент) є єдиною, яка дає чітку пораду щодо використання методу.
CodeFox

4

Слід зазначити, що Cast(Of T)його можна використовувати на IEnumerableвідміну від інших функцій LINQ, тому, якщо коли-небудь трапляється випадок, коли вам потрібно використовувати LINQ в колекції або загальному списку, такому як ArrayList, ви можете використовувати Cast(Of T)для передачі на місце, IEnumerable(Of T)де LINQ може працювати.


2

Cast()спробує передати всі елементи колекції (і викине виняток, якщо елемент неправильного типу), при OfType()цьому поверне лише елементи належного типу.


2

OfTypeбуде фільтрувати елементи, щоб повернути лише ті, що вказані типу. Castвийде з ладу, якщо елемент не можна передати цільовому типу.


2

Cast<T>спробує передати всі елементи даному типу T. Цей виступ може провалитись або викинути виняток. OfType<T>поверне підмножину оригінальної колекції та поверне лише ті об’єкти, що мають тип T.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.