当我将List<T>
投射到我自己的集合时,有什么方法可以避免额外的演员表,这只是List<T>
的衍生物吗?
ScreenCollection screens = screenRepository.GetAll().ToList();
// fails because ScreenCollection != return of ToList() which is List<Screen>
// However,
public class ScreenCollection : List<Screen>
ScreenCollection screens = screenRepository.GetAll().ToList();
// fails because ScreenCollection != return of ToList() which is List<Screen>
// However,
public class ScreenCollection : List<Screen>
我知道我可以做到以下这点,很简单:
ScreenCollection screens = (ScreenCollection)screenRepository.GetAll().ToList();
如果可能的话,我想避免额外的施法。
答案 0 :(得分:9)
这是不可能的,事实上,你的演员也是错的。仅仅因为ScreenCollection
派生自List<Screen>
并不意味着每个List<Screen>
实例都会实现ScreenCollection
。
.NET 4.0和C#4将在接口类型上提供逆变和协方差,这将在某种程度上缓解您所面临的情况,但它不会为列表提供差异。
解决问题的一种方法是为ScreenCollection
设置一个扩展方法或构造函数(取决于您是否拥有代码),可以根据给定的IEnumerable<Screen>
创建新实例或IList<Screen>
。您还可以考虑重构您的ScreenCollection
类型(如果它是您的重构),以便它封装List<Screen>
而不是从它继承,然后从{包装新的List<Screen>
实例{1}}。
答案 1 :(得分:7)
子类化List<T>
很少有用 - 除了给它起个名字; Collection<T>
至少为您提供了覆盖某些内容的选项......
在您的示例中,我假设.ToList()
是LINQ扩展方法 - 在这种情况下,它确实返回List<T>
,而不是ScreenColleciton
。 你可以添加一个隐式转换运算符,但我认为这不是一个好主意(事实证明这不是一个好主意:它是不可能的;-p credit:Aistina - 评论)。
如果不是 LINQ扩展方法 - 那么只需输入它就可以返回正确的内容......
答案 2 :(得分:2)
实际上,演员甚至不会工作。您可以将ScreenCollection转换为列表<
屏幕>
但不能反过来做。考虑一下 - 如果您在ScreenCollection类中添加了一个普通List上不存在的额外属性,该怎么办?如果您可以将任何List <
屏幕>
强制转换为ScreenCollection,那么此属性的值是多少?
相反,您可以使用List <
T >
构造函数,该构造函数将IEnumerable <
T >
作为参数:
var screens = new ScreenCollection(screenRepository.GetAll());
答案 3 :(得分:0)
我认为在.NET 3.0中不可能......在4.0中,你不需要强制转换。
答案 4 :(得分:0)
没有简单的方法可以做到这一点 -
演员表也会失败,因为(在运行时),List<Screen>
不是ScreenCollection
。
如果你使你的类实现IList<Screen>
而不是派生List<Screen>
,并将列表封装为成员变量,你可能会创建一个构造函数来获取现有列表并将其“包装”在你的班。这将允许你写:
ScreenCollection screens = new ScreenCollection(screenRepository.GetAll().ToList());
答案 5 :(得分:0)
为什么不在存储库上创建泛型方法覆盖。类似的东西:
var screens = screenRepository.GetAll&lt; ScreenCollection&gt;();