Enumerable.Cast <T>копирует объекты? - PullRequest
2 голосов
/ 08 февраля 2012

У меня есть иерархия объектов

public class MyBase {}
public class MyDerived : MyBase {}

, и у меня есть

List<MyBase> myList;

, которая фактически заполнена экземплярами MyDerived

Для доступа к этому спискукак List<MyDerived>, я делаю следующее:

myList.Cast<MyDerived>().ToList()

Я читаю документы MSDN на Enumerable.Cast<T>, но мне не ясно, являются ли Cast<T> иОперации ToList создают новую копию объектов в памяти или просто позволяют компилятору обращаться к существующим объектам, как если бы они были List<MyDerived>.

Ответы [ 3 ]

5 голосов
/ 08 февраля 2012

Как следует из названия, Cast<T>() просто отбрасывает объекты:

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) { 
    IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
    if (typedSource != null) return typedSource; 
    if (source == null) throw Error.ArgumentNull("source");
    return CastIterator<TResult>(source);
}

static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) {
    foreach (object obj in source) yield return (TResult)obj; 
} 

В .Net принципиально невозможно скопировать произвольный объект. Cast<T>() не имеет смысла копировать вещи.

Обратите внимание, что если T является типом значения, Cast<T>() будет копировать структуры; типы значений всегда копируются. (кроме случаев, когда они передаются как ref параметры)

0 голосов
/ 08 февраля 2012

Активный вызов:

enumerable.Cast<T>();

эквивалентен:

enumerable.Select(x=>(T)x)

И:

enumerable.ToList<T>()

эквивалентен:

List<T> myList = new List<T>();
foreach(T item in enumerable)
{
   myList.Add(item);
}

so ...

enumerable.Cast<T2>.ToList()

эквивалентно:

List<T2> myList = new List<T2>();
foreach(T item in enumerable)
{
   myList.Add((T2)item);
}

Оба из них будут быстро взорваны, если перечислимый содержит какие-либо записи, не относящиеся к типу, приведенному к T2.

Было бы безопаснее, как

  enumerable.Where(x=>x is T2).Cast<T2>().ToList();

или

  enumerable.OfType<T2>().ToList();

Однако ни один из этих объектов не копирует объекты, содержащиеся в исходной коллекции.Они просто создают коллекции, содержащие ссылки на оригинальные объекты.

0 голосов
/ 08 февраля 2012
нет

Нет

Неудивительно (!) Это Casts их.

Я прочитал документы MSDN на Enumerable.Cast, но мне не ясно, создают ли операции Cast и ToList новую копию объектов в памяти или просто позволяют компилятору обращаться к существующим объектам, как если бы они были Список.

Да, именно этот сценарий позволит компилятору получить доступ к существующим объектам, как если бы они были List<MyDerived>

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