很确定 aList<SubClass>
与 不协变List<BaseClass>
。IEnumerable<T>
也许,但不是 List 因为您可以自由添加一个非T
(但仍然IDataTransferObjects
)会引发运行时异常,因此它在编译时被捕获。
虽然您的代码在运行时可能是安全的(因为您按类型使用键),但编译器并不知道这一点。
List<Animal> animalList = new List<Animal>();
animalList.Add(new Dog()); //ok!
List<Cat> catList = new List<Cat>();
animalList = catList; //Compiler error: not allowed, but it's what you're trying to do
animalList.Add(new Dog()) //Bad stuff! Trying to add a Dog to a List<Cat>
如果您试图将其视为IEnumerable<IDataTransferObject>
无法通过代码修改的那些,那么您正在做的事情将起作用(除非您首先将其强制转换,如果您使用错误的类型,它将通过/失败)。但List
绝对可以通过编译时代码进行更改。
编辑:如果您不介意强制转换,并且真的想要一个List<T>
(因此您的调用代码是类型安全的,并且T
一旦检索到就不会添加非对象)您可以执行以下操作:
private Dictionary<Type, object> dataStore = new Dictionary<Type, object>();
public void Insert<T>(T dto) where T : IDataTransferObject
{
object data;
if (!dataStore.TryGetValue(typeof(T), out data))
{
var typedData = new List<T>();
dataStore.Add(typeof(T), typedData);
typedData.Add(dto);
}
else
{
((List<T>)data).Add(dto);
}
}
//you didn't provide a "getter" in your sample, so here's a basic one
public List<T> Get<T>() where T : IDataTransferObject
{
object data;
dataStore.TryGetValue(typeof(T), out data);
return (List<T>)data;
}
调用代码如下:
Insert(new PersonDTO());
Insert(new OrderDTO());
Insert(new PersonDTO());
List<PersonDTO> persons = Get<PersonDTO>();
List<OrderDTO> orders = Get<OrderDTO>();
Console.WriteLine(persons.Count); //2
Console.WriteLine(orders.Count); //1
所以从外部看,所有 API 的使用都是类型安全的。它不是orders
a List<IDataTransferObject>
(这意味着您可以添加非OrderDTO
对象),而是强类型并且不能混合和匹配。
当然,在这一点上,没有真正需要限制到IDataTransferObject
,但这取决于您和您的 API/设计/使用。