2013-03-01 4 views
9

내 프로젝트에는 MyClass이 있으며 IMyClass을 구현합니다. 다른 항목의 목록을 변환하여 IMyClass의 목록을 반환해야합니다. 간단히하기 위해 다른 항목을 해당 생성자에 전달하여 즉 new MyClass(item)과 같이 MyClass을 만들 수 있다고 가정합니다.람다에 던지거나 IEnumerable을 캐스팅해야합니까?

그 옵션 # 1 더블 열거를 필요로 나에게 보인다
var option1 = items.Select(item => new MyClass(item)).Cast<IMyClass>().ToList() 
var option2 = items.Select(item => new MyClass(item) as IMyClass).ToList() 

, 한 번에 모든 항목을 캐스팅 :

은 (내가 아는 한) 같은 결과를 다음 두 줄을 고려 내 인터페이스 및 한 번 목록을 생성 할 수 있습니다. 내가 옳다면 옵션 2가 더 똑똑해 질 것입니다. 그러나 은 옵션 # 2와 같은 코드를 사용하여 본 적이 없으며 나머지 C# 커뮤니티가하지 못했던 영리한 것을 생각해 내기에 충분히 똑똑하지 않다고 생각하는 경향이 있습니다.

옵션 2는 더 심미적으로 즐거운 옵션이라고 생각하지만 그건 저뿐입니다.

내 질문 :은 제 생각으로는 # 2 더 좋은 생각입니다. 내가 누락되었거나 다른 이유 중 하나 인 옵션 # 1을 계속 사용하고자하는 이유가 있습니까? 또는 내가 완전히 실종 된 똑똑한 3 분의 1이있을 때 아마도 어리석은 아이디어 두 개를 비교했을까요?

+3

enumerables가 게으르고 구성 가능하다는 것을 잊지 마십시오! 옵션 1은 그것을 두 번 열거하지 않을 것입니다 ... –

+0

왜'MyClass'가'IMyClass'를 구현하면 캐스트해야합니까? –

+1

당신은 추론없이 언제든지 유형을 철자 할 수 있다는 것을 알고 있습니까? 이 메소드는'IEnumerable '를 리턴합니다. :) –

답변

17
as를 사용하지 않는,

var option3 = items.Select<Foo, IMyClass>(item => new MyClass(item)) 
        .ToList() 

또는 그러나 다만 일반적으로 주조 :

나는 옵션 3 가고 싶어

var option4 = items.Select(item => (IMyClass) new MyClass(item)) 
        .ToList() 

두 가지 모두 Cast을 사용하는 것보다 더 깨끗하게 보입니다.

아, 그리고 같은 .NET 4 (때문에 공분산에), 대신 ToList 통화 형식 인수를 넣을 수와 C# 4 :

var option5 = items.Select(item => new MyClass(item)) 
        .ToList<IMyClass>() 
+0

옵션 3과 4는 나를 미학적으로하지 않았지만 옵션 5는 분명히 그렇습니다. 선택의 만세! – ean5533

+0

옵션 4는 'var option4 = items.Select (item => (** IMyClass **) new MyClass (item))'가 아니어야합니까? – pescolino

+0

@pescolino : 예, 정말로 고쳐졌습니다. 고마워요. –

3

그 옵션 # 1 이것은 사실이 아니다 더블 열거

을 필요로 나에게 보인다. 두 경우 모두 ToList()에 도달하면 items 컬렉션 만 열거됩니다.

라인은

var option1 = items.Select(item => new MyClass(item)).Cast<IMyClass>().ToList() 

둘 사이의 유일한 차이점은 첫 번째 두 개의 기능 항목마다 호출이 필요하다는 것이다

var option1 = items.Select(item => new MyClass(item)).Select(x => (IMyClass)x).ToList() 

동등 (C 번호가 든 람다를 인라인하지 않는 한 I 믿을 수 없다.) 두 번째 옵션은 하나만 있으면됩니다.

개인적으로 나는 두 번째 스타일을 스타일의 문제로 생각합니다.

+0

+1. 2 가지를 골라 내 개인적인 이유 - 나는 그런 맥락에서'캐스트'를 좋아하지 않는다. 컬렉션에 넣을 항목을 결정할 수 없음을 보여줍니다. 많은 경우에'List '의 특별한 유형이 필요하지 않다면'IEnumerable '이 필요한 곳에서'IEnumerable '을 사용할 수 있습니다 - 그래서 실제로 코드를 읽기 쉽게 만드는 경우가 있습니다 . –

1

당신이 사용하는 것은 선호도의 문제이며, 우리가 정말로 당신을 위해 대답 할 수없는 것입니다.

하지만 직감이 정확하다면 Cast은 반복에 두 번째 반복 레이어를 추가합니다. 그것은 아주 사소한, 그리고 나는 그것이 성능 측정 가능한 차이가 발생합니다 의심하지만, Cast 방법은 기본적으로이 수행하는 새로운 IEnumerable 객체를 반환 :

foreach (object obj in source) yield return (TResult)obj; 

효과 호출 스택에있는 대부분의 다른 수준입니다; yield을 사용하기 때문에 다른 대부분의 IEnumerable 메서드처럼 요청시에만 반복됩니다. 하지만 iterator state는 2 단계로 리턴해야합니다. 당신에게 중요한 것이 당신 자신의 어플리케이션을 위해 측정 할 필요가있는 것인지 여부.

(또한,이. 즉, 귀하의 옵션 # 2를 선호하는 또 다른 이유는 캐스트가 유효하지 않은 경우 예외가 발생할 수 있습니다 안전하지 않은 캐스트,이다 않는 최소한의 기준 소스에 따라, 점에 유의.)

1

당신은 항상 당신의 선택에 명시 적 형식 인수를 제공 할 수 있습니다

var option2 = items.Select<IItem,IMyClass>(item => new MyClass(item)).ToList(); 

여기서 IItem은 항목을 캐스팅 할 수있는 유형 또는 인터페이스입니다.

관련 문제