无法从DerivedT <Derived2T>转换为BaseT <base2T>

elC*_*iro 2 .net c# generics .net-4.0 variance

我有这些类,一个活动记录模式的实现:

public abstract class RecordCollection<T> : ObservableCollection<T> where T : Record
public abstract class Record : INotifyPropertyChanged
Run Code Online (Sandbox Code Playgroud)

每次我想定义一行数据库(即一个联系人)时,我都会创建一个新的记录类,如:

public class Contact : Record
Run Code Online (Sandbox Code Playgroud)

以及一系列数据库(即联系人)的集合:

public class ContactCollection : RecordCollection<Contact>
Run Code Online (Sandbox Code Playgroud)

但之后我不能使用generic来包含一个记录colletcion:

ContactCollection contColl = new ContactCollection(databaseman dbMan);
contColl.Load();

RecordCollection<Record> recordColl = contColl;
Run Code Online (Sandbox Code Playgroud)

它给我"不能隐式转换类型ContactCollection到>".任何帮助,将不胜感激.

InB*_*een 6

不允许这种投射只是因为这可能发生:

public class AnotherTypeOfContact: Record {}
Run Code Online (Sandbox Code Playgroud)

现在我们可以做到:

recordColl.Add(new AnotherTpyeOfContact()) //runtime exception as no conversion between AnotherTypeOfContact and Contact
Run Code Online (Sandbox Code Playgroud)

这就是泛型类型之间所谓的协方差逆变(在此处阅读更多).要使其工作,contColl必须实现一个"out"唯一的接口,它不会.通过这个我的意思是,为了保持类型安全,contColl不能允许添加项目(更正式,T只能是方法的返回类型)

请注意,在数组中这允许的,但它是一个破坏的协方差,这是不幸的:更多在这里