为简洁起见,我将在这里通用。我有一个基类 - 评论 - 有一个孩子 - 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列表以退出方法作为其父类型列表(Review)?
仅仅是一个FYI,调用此方法的代码不打算关注它所获得的类型评论。后续代码将以任何方式运行。
我很欣赏它。
答案 0 :(得分: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>
,还有另一种选择:
public List<Review> GetReviews(string filePath)
{
XElement xmlDoc = XElement.Load(filePath);
IEnumerable<Review> dtos = ...; // As before
return dtos.ToList();
}
请注意dtos
类型的明确说明。查询表达式的类型为IEnumerable<ShelfAwarenessReview>
,但可以隐式转换(在C#4中)到IEnumerable<Review>
。
答案 1 :(得分:3)
变化:
reviews = dtos.ToList();
要:
reviews = dtos.Cast<Review>().ToList();
问题是List和List不是协变的。如果您考虑一下,这很容易理解:
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());
答案 2 :(得分:3)
使用Cast转换为基本类型:
return dtos.Cast<Review>().ToList();
答案 3 :(得分:3)
这是Covariance的问题。对于您的特定问题,请尝试:
return dtos.ToList().Cast<Review>();
答案 4 :(得分:1)
使用这个
List<Review> reviews = dtos.Cast<Review>().ToList();
答案 5 :(得分:1)
您无法将列表转换为列表。假设你可能会发生可怕的事情:
List<String> list = new list<String>();
list.Add("Hello");
List<Object> list2 = List<Object>(list);
list2.Add(12);
咦?我是否只是将一个整数添加到字符串列表中。这就是为什么你不能。你应该阅读协方差和逆变。
答案 6 :(得分:1)
List<Review> reviews = dtos.Cast<Review>().ToList();