这编译:
class ReplicatedBaseType
{
}
class NewType: ReplicatedBaseType
{
}
class Document
{
ReplicatedBaseType BaseObject;
Document()
{
BaseObject = new NewType();
}
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
class DalBase<T> : where T: ReplicatedBaseType
{
}
class DocumentTemplate
{
DalBase<ReplicatedBaseType> BaseCollection;
DocumentTemplate ()
{
BaseCollection= new DalBase<NewType>(); // Error in this line. It seems this is not possible
}
}
Run Code Online (Sandbox Code Playgroud)
什么原因?
正如安德烈所说,你想要(通用)协方差.然而:
要进入最后一点,假设DalBase<T>有这样的方法:
void AddEntity(T entity)
Run Code Online (Sandbox Code Playgroud)
现在你已经有了这样的东西,你希望能够编译 - 但显然是危险的:
DalBase<Fruit> fruitDal = new DalBase<Banana>();
fruitDal.AddEntity(new Apple());
Run Code Online (Sandbox Code Playgroud)
第二行必须编译 - 所以为了在编译时失败,它必须是第一行失败.
我最近就通用差异进行了一个小时的讨论,如果你想了解更多信息,你可能会觉得有用 - 请参阅NDC 2010视频页面并搜索"差异".另外,您可以阅读Eric Lippert关于该主题的博客文章 - 但请注意,这可能需要一个多小时;)
C#4.0目标.NET 4中存在差异,但仅限于in/ out(哦和参考类型数组)的接口和用法.例如,要制作协变序列:
class DalBase<T> : IEnumerable<T> where T: ReplicatedBaseType
{
public IEnumerator<T> GetEnumerator() {throw new NotImplementedException();}
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
}
class DocumentTemplate
{
IEnumerable<ReplicatedBaseType> BaseCollection;
DocumentTemplate()
{
BaseCollection = new DalBase<NewType>(); // Error in this line. It seems this is not possible
}
}
Run Code Online (Sandbox Code Playgroud)
但除此之外......不.坚持使用非通用列表(IList),或使用预期的列表类型.