2011-11-16 3 views
2

간결함을 위해 여기서는 일반적으로 사용합니다. 나는 기본 클래스가있다 - 리뷰 - 아이가있다 - ShelfAwarenessReview.부모 목록에 자식 목록 캐스팅

public List<Review> GetReviews(string filePath) 
     { 
      XElement xmlDoc = XElement.Load(filePath); 

      var dtos = from item in xmlDoc.Descendants("message") 
         select new ShelfAwarenessReview() 
         { 
          PubDate = item.Element("meta").Attribute("permlinkdate").Value, 
          Summary = item.Element("meta").Element("summary").Value, 
          Isbn = item.Element("BookInfo").Element("ISBN").Value 
         }; 

      List<Review> reviews = new List<Review>(); 
      reviews = dtos.ToList(); 

      return reviews; 
     } 

지금, 나는이 점점 오전 오류가 List<ShelfAwarenessReview>List<Review>에 암시 적으로 캐스팅 할 수 없다는 것입니다 :

은 또한 누구의 서명 인터페이스에 필요한 방법을 가지고있다.

저는 여러 가지 유형의 캐스팅을 시도했는데, 적어도 제가 생각한대로 작동하지 않습니다. ShelfAwarenessReview는 Review의 하위 항목이므로이 기능이 작동한다고 생각했습니다. "모든 토스터는 가전이지만 모든 가전 제품이 토스터가 아닙니다."...

목록에서 메소드를 종료하려면 ShelfAwarenessReviews 목록을 가져 오려면 어떻게해야합니까? 상위 유형 (검토)?

참고로이 코드를 호출하는 코드는 형식 검토에 신경 쓰지 않으려 고합니다. 후속 코드는 무엇이든 작동합니다.

정말 고맙습니다.

답변

6
그럼 당신이 다음 :

여기 간단한 해결책 무시 빈 List<Review> 만들 필요가 없습니다, 시작하는

:

:
public List<Review> GetReviews(string filePath) 
{ 
    XElement xmlDoc = XElement.Load(filePath); 

    var dtos = ...; // As before 

    return dtos.Cast<Review>().ToList(); 
} 

는 .NET 4, C# 4를 사용하는 경우는, 때문에 IEnumerable<T> 작동하지만 List<T> 일반적인 공분산에 또 다른 대안있다

dtos 유형의 명시 적 사양에 유의하십시오. 쿼리 식은 IEnumerable<ShelfAwarenessReview>이지만 암시 적으로 (C# 4에서는) IEnumerable<Review>으로 변환됩니다.

+0

축복이 있습니다, 친절합니다. 조금도. 공분산과 상향식을 이해하는 데 더 익숙해 져야합니다. 당신이 처음 이었으므로 당신은 내 승인 확인을받습니다. 고마워요. –

3

변경 :

reviews = dtos.ToList(); 

사람 :

reviews = dtos.Cast<Review>().ToList(); 

문제는 그 목록과 목록 공변 수 없습니다. 당신이 그것에 대해 생각한다면 그것은 쉽게 이해할 수 :

List<ShelfAwarenessReview> initial = new List<ShelfAwarenessReview>(); 
List<Review> cast = (List<Review>)initial; 

// The underlying type is still List<ShelfAwarenessReview>. 
// SomeOtherReview inherits Review but not ShelfAwarenessReview 
// What will happen when I make the following call? 
cast.Add(new SomeOtherReview()); 
+0

@JustinNiesnner 많은 사람들이 이미 답변을 올렸지 만 입력 해 주셔서 감사합니다. +1 노력, :). –

3

사용 캐스트는 기본 유형으로 변환 :

return dtos.Cast<Review>().ToList(); 
+0

많은 사람들이 이미 답변을 게시했지만 입력 해 주셔서 감사합니다. +1 노력 : –

3

그것은 Covariance의 문제입니다. 특정 문제에 대한 시도 :이 하나

List<Review> reviews = dtos.Cast<Review>().ToList(); 
+0

그래서 많은 사람들이 이미 답변을 게시했지만 귀하의 의견을 보내 주셔서 감사합니다. +1 노력 : –

1

사용.당신이 할 수 있다고 가정하면, 끔찍한 일이 일어날 것입니다 :

List<String> list = new list<String>(); 
list.Add("Hello"); 
List<Object> list2 = List<Object>(list); 
list2.Add(12); 

어? 방금 문자열 목록에 정수를 추가 했나요? 그것이 당신이 할 수없는 이유입니다. 당신은 공분산과 반항에 대해 읽어야합니다.

1

당신은 목록이 목록에 캐스팅 할 수

return dtos.ToList().Cast<Review>(); 
+0

나는 당신의 요점을 참조하십시오. 예를 들어 주셔서 감사합니다. .NET 4/contra variance에 대한 몇 가지 문제가 해결되었다는 것을 알고 있습니다. 나는 이것에 대해 더 많이 알 필요가 있습니다. 나는 아직도 그것에 대한 출처를 찾고있다. 예를 들어 주셔서 다시 한 번 감사드립니다. –

+1

문제가 없으면 다음을 참조하십시오. http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/default.aspx – zmbq

1
List<Review> reviews = dtos.Cast<Review>().ToList();