是否Enumerable.Cast <t>复制对象?</t>

时间:2012-02-08 18:00:26

标签: c# casting

我有一个对象层次结构

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

并且

List<MyBase> myList;

实际上填充了MyDerived

的实例

为了以List<MyDerived>的形式访问该列表,我正在执行以下操作:

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

我在Enumerable.Cast<T>上阅读了MSDN文档,但我不清楚Cast<T>ToList操作是否会创建对象的新副本内存,或者只是允许编译器访问现有对象,就像它们是List<MyDerived>一样。

3 个答案:

答案 0 :(得分:5)

顾名思义,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参数传递时除外)

答案 1 :(得分:0)

没有

不出所料(!)Casts他们。

  

我在Enumerable.Cast上阅读了MSDN文档,但我不清楚Cast和ToList操作是否在内存中创建了对象的新副本,或者只是允许编译器访问现有对象,就好像它们是列表。

是的,具体来说,这种情况将允许编译器访问现有对象,就好像它们是List<MyDerived>

一样

答案 2 :(得分:0)

演员表:

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);
}

所以...

enumerable.Cast<T2>.ToList()

相当于:

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

如果enumerable包含任何不属于T2的类型的条目,那么这两个条目都会立即爆炸。

它会更安全

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

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

但是,这些都不会复制原始集合中包含的对象。它们只是创建包含对原始对象的引用的集合。