将子类型列表转换为父类型列表
本文关键字:类型 列表 父类 转换 | 更新日期: 2023-09-27 18:14:46
为简洁起见,我将在这里使用通用名称。我有一个基类- Review -它有一个子类- 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)的列表中的方法?
仅供参考,调用该方法的代码并不关心它所获得的类型审查。
我非常感谢。
首先,您不需要创建一个空的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>
。
变化:
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());
使用强制类型转换为基类型:
return dtos.Cast<Review>().ToList();
这是协方差的问题。对于您的特定问题,请尝试:
return dtos.ToList().Cast<Review>();
不能将List强制转换为List。假设你可以,可怕的事情会发生:
List<String> list = new list<String>();
list.Add("Hello");
List<Object> list2 = List<Object>(list);
list2.Add(12);
啊?我刚才是不是给字符串列表加了一个整数。这就是为什么你不能。你应该读一读协方差和逆变性
List<Review> reviews = dtos.Cast<Review>().ToList();
使用这个
List<Review> reviews = dtos.Cast<Review>().ToList();