2013-03-24 4 views
7

사용자가 원하는 유형의 목록을 반환하는 메서드를 만들려고합니다. 이렇게하려면 제네릭을 사용하고 있습니다. 익숙하지 않아서이 질문이 명백 할 수 있습니다. 문제는이 코드가 작동하지 않는다는 것입니다 및 오류 메시지를 Cannot convert type Systems.Collections.Generic.List<CatalogueLibrary.Categories.Brand> to Systems.Collection.Generic.List<T>IList를 사용할 수 있지만 일반 메서드의 List는 사용할 수 없습니다.

private List<T> ConvertToList<T>(Category cat) 
{    
    switch (cat) 
    { 
     case Category.Brands: 
      return (List<T>)collection.Brands.ToList<Brand>(); 

    } 
    ... 
} 

을 던졌습니다하지만 대신 IList를 사용하는 경우, 오류가 없습니다.

private IList<T> ConvertToList<T>(Category cat) 
{    
    switch (cat) 
    { 
     case Category.Brands: 
      return (IList<T>)collection.Brands.ToList<Brand>(); 

    } 
    ... 
} 

이 경우 목록이 아닌 IList를 사용할 수 있습니까? collection.Brands는 제 3 자 라이브러리에서 BrandCollection 유형을 반환하므로 그 생성 방법을 알 수 없습니다. BrandCollection은 IList에서 파생 될 수 있으며 (그러면 그냥 추측 할 수 있습니다.) 따라서 일반 List가 아닌 IList로 변환 될 수 있습니까?

+0

거기에 유형 제약 조건을 넣어야합니다! 빌어 먹을 물건을 빌려줄 필요가 없습니다. – antonijn

+3

두 번째 예제는'return (IList ) 컬렉션이 아닙니다 .Brands.ToList ();'? – Matthew

+0

나는이 일이 끝난 후에 살펴 보려고했다. 나는 제네릭에 조금 익숙해 져서 나중에 다른 것을 부러 뜨릴 경우를 대비해서 그 것을 떠날 것이라고 생각했다 : D 제약 조건은'어디에 T : 브랜드'(및 다른 카테고리)가 될 것인가? – XSL

답변

9

T에는 제약 조건이 없으므로 컴파일시에만 object으로 변환 할 수 있습니다. IList<object>을 구현하고 List<Brand>을 상속받은 새로운 클래스가 이론적으로 생성 될 수 있으므로 인터페이스 유형에 대한 캐스트는 컴파일러에서 검사하지 않습니다. 그러나 List<object>List<Brand>을 상속하는 클래스를 만들 수 없으므로 List<T>으로 캐스팅되지 않습니다. 그러나 귀하의 경우 T 유형이 귀하의 switch 성명을 통해 무엇인지 알고 있으며 강제로 전송하려고합니다.

private List<T> ConvertToList<T>(Category cat) 
{    
    switch (cat) 
    { 
     case Category.Brands: 
      return (List<T>)(object)collection.Brands.ToList<Brand>(); 
    } 
} 

여기에 더 큰 설계 문제는, 그러나, 당신은 T 알려진 유형의 개별 목록을 때 제네릭이 최선의 선택 아니라는 것이다 다음과 같이이 작업을 수행하려면 object 첫째을 통해 캐스팅. T이 무엇이든 될 수 있거나 기본 유형 또는 인터페이스로 제한 될 때 제네릭이 더 좋습니다. 여기에서, 당신은 switch 문의 각 지점에 대해 별도의 방법을 쓰는 것이 더 줄이없이

private List<Brand> ConvertToBrandList() 
{ 
    return collection.Brands.ToList<Brand>(); 
} 

, 당신은 매우 작은 형태의 안전성 있습니다. 누군가가 ConvertToList<int>(Category.Brands)으로 내 전화를하면 어떻게 되나요?

+0

을 사용해 주셔서 감사합니다. 'object' 메쏘드가 효과가 있었지만, 나는 개별 메쏘드 길을 갈 것입니다. 방금 봉인 된 클래스라는 사실을 알았 기 때문에 '브랜드'에 제약을 가할 수 없었습니다. – XSL

+0

+1. 나는 진짜 이유가 C# reference 6.2.4에 기인한다고 생각한다 : "명시 적 참조 변환은 ...\t S 클래스가 S *에서 * 모든 인터페이스 유형 T *로 제공되는 경우 S는 봉인되지 않았고 S는 T를 구현하지 않습니다. " –