2012-02-08 2 views
2

나는 객체 계층 구조Enumerable.Cast가 <T> 개체 복사?

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

실제로 List<MyDerived>로 그 목록에 액세스하려면 MyDerived

의 인스턴스로 가득

List<MyBase> myList; 

, 내가하고있어이에게이 다음 :

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

나는 Enumerable.Cast<T>에 MSDN의 문서를 읽을 수 있지만, Cast<T>ToList 작업이 새로운 사본 메모리에있는 개체의, 또는 단순히이 액세스에 컴파일러를 할 수 있도록 여부 나에게 분명하지 않다 기존의 객체가있는 것처럼 List<MyDerived>.

+1

실제로 임의의 관리 대상 객체를 복사하는 것이 _impossible_입니다. – SLaks

답변

5

인 것처럼 컴파일러는 기존 개체에 액세스 할 수 있습니다 임의의 객체를 복사하는 것은 근본적으로 불가능합니다. 사물을 복사하려면 Cast<T>()에 대해 아무런 의미가 없습니다.

T이 값 유형 인 경우 Cast<T>()입니다. 구조체를 복사하십시오. 값 유형은 이며 항상입니다. (ref 매개 변수로 전달하는 경우를 제외하고)

+0

ToList()를 사용하면 사본이 생성되거나 생성되지 않습니까? – sos00

+0

@ sos00 : 틀린 내용입니다. 개체를 복사하는 것은 불가능합니다. 'ToList()'는 _list_의 사본을 만들지 만 여전히 같은 객체를 참조합니다. – SLaks

+0

여기에 직접 언급 한 내용을 언급하는 것이 유용 할 수 있습니다.이 코드를 구현하는 경우 정확히 유형을 포함하는 어셈블리가 _inside_와 같이 작동하면 표준 확장이하는 것과 다를 수 있습니다.'(TResult) obj'는 사용자 정의 변환 연산자를 호출 할 수 있습니다 (예 :'class X {public static implicit operator Y() {...}') – sehe

0

없음

당연히 (!)이 Casts 그들.

나는 Enumerable.Cast에서 MSDN 문서를 읽었지 만 Cast 및 ToList 작업이 메모리에있는 개체의 새 복사본을 만들지 여부는 분명하지 않거나 단순히 컴파일러가 기존 개체에 액세스 할 수 있도록 허용합니다. 그들은 목록이었다. 닷넷에서

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

: 이름에서 알 수 있듯이

예, 특히이 시나리오는 Cast<T>() 그냥 객체를 캐스트, 그들이 List<MyDerived>

+0

사용자 정의 변환은 순전히 컴파일 타임 기능입니다. 런타임 메소드는이 메소드를 사용하지 않습니다. – SLaks

+0

@ SLAKs : 다시 한 번 감사드립니다. 나는 오늘 무언가를 배웠다. 그리고 당신은 나를 시험해보기위한 노력을 덜어주었습니다 :) – sehe

0

캐스트 호출 :

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

그리고 :

enumerable.Cast<T>(); 

에 해당

:

enumerable.ToList<T>() 

은 동일합니다

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

so ...열거가 T2 스트 종류의 아닌 모든 항목이 포함 된 경우 신속하게 날려 버리겠다 둘

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

:

enumerable.Cast<T2>.ToList() 

은 동일합니다.

그것은 것이 안전 등

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

또는 그러나

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

, 객체가 원래의 컬렉션에 포함이 사본의 없음. 그들은 단지 원래 객체에 대한 참조를 포함하는 콜렉션을 생성합니다.

+0

새 목록 에 대해 _is_ 메모리가 할당 되었습니까? –

+0

예.메모리는 목록 데이터 구조에 할당됩니다. –

+0

참고 : 정의 된 형식을 필터링하고 캐스트하는 OfType 확장 메서드를 사용하는 다른 방법을 추가했습니다. (enumerable.OfType () .ToList())는 T2 유형에 캐스트 가능한 요소 목록 만 반환합니다. –

관련 문제