2011-04-13 6 views
4

나는 데이터베이스에서 목록을 통해 열거하는 데 사용하는 클래스가 있습니다. 데이터베이스의 모든 테이블은 고유 한 속성을 가진 자체 클래스를 가지고 있으며 모두 DatabaseTableRow에서 파생됩니다.캐스팅 IEnumerable <Derived> to IEnumerable <BaseClass>

public class DatabaseLinkRowsEnumerator<T> : IEnumerator<T>, IEnumerable<T> where T : DatabaseTableRow 

저는 DatabaseTableRow에서 파생 된 Page에서 파생 된 User 클래스가 있습니다. 그런 다음 사용자 목록 인 DatabaseLinkRowsEnumerator를 반환하는 속성이 있습니다.

이미지, 이름 및 링크가 포함 된 가로 목록의 모든 페이지 목록을 표시하는 UI 기능도 있습니다.

protected string GetVerticalListModuleHtml(IEnumerable<Page> pages) 

이제는 DatabaseLinkRowsEnumerator의 값을이 함수에 전달하고 싶습니다. User는 Page에서 파생되며 DatabaseLinkRowsEnumerator는 IEnumerator입니다. 전송하려고해도 다음 오류가 발생합니다.

Unable to cast object of type 'Database.DatabaseLinkRowsEnumerator`1[Database.User]' to type 'System.Collections.Generic.IEnumerable`1[Database.Page]'. 

ASP.NET 2.0을 사용하고 있습니다. 누구든지 어떻게 각각의 전체 복사본을 만들지 않고 이것을 캐스팅/변환하는 방법에 대한 아이디어가 있습니까?

답변

12

.NET 2.0을 사용하면, 약간 어색하지만 너무 하드 :

public static IEnumerable<TBase> Cast<TDerived, TBase> 
    (IEnumerable<TDerived> source) 
    where TDerived : TBase 
{ 
    foreach (TDerived item in source) 
    { 
     yield return item; 
    } 
} 

이처럼 전화 :

IEnumerable<Page> pages = UtilityClass.Cast<User, Page>(users); 

이 유유히을 평가합니다. LINQ 그것은 쉽게 - 당신이 Cast 확장 메서드를 사용합니다 :)

+0

상속을 올바르게 설정했지만 OP 게시물에 보이지 않는 경우에도 마찬가지입니다. DatabaseTableRow와 Page 사이의 관계. –

+0

@ Justin, OP는 DatabaseTableRow에서 Page가 파생되었다고 말했습니다. –

+0

약간 혼란스러워집니다.이 방법을 어디에 넣을까요? – Connell

4

당신은 그렇게 할 수 있도록 IEnumerable<DerivedClass>에서 이미 IEnumerable<BaseClass>에 대한 참조 형식 변환 거기 T에서

.NET 4에서
var baseSequence = derivedSequence.Cast<BaseClass>(); 

IEnumerable<T>는 공변를 :

DatabaseLinkRowsEnumerator<User> users = ... 
IEnumerable<Page> = users.Cast<Page>(); 

편집 : Cast 확장 방법은 .NET 2.0에서 사용할 수 없습니다. Jon Skeet의 구현을 대신 정상적인 정적 메서드로 사용할 수 있습니다. VS2008을 사용하는 경우 LinqBridge을 사용하면 .NET 2.0을 타겟팅 할 때 Linq를 객체로 사용할 수 있습니다.

+0

Enumerable.Cast <>() LINQ 메서드, .NET 3.5에서 도입 된 아닌가요? – adamjford

+1

@adamjford, 예, 제 편집 참조 –

관련 문제