不应该';变异协方差/逆变换在C#4.5中允许吗? private Dictionary dataStore=new Dictionary(); 公共无效插入(T dto),其中T:IDataTransferObject { if(!dataStore.ContainsKey(typeof(T))) { Add(typeof(T),newlist()); } 数据存储[类型(T)]。添加(dto); }
上面的代码给了我数据存储上的编译错误。添加行是因为它不喜欢我尝试将不应该';变异协方差/逆变换在C#4.5中允许吗? private Dictionary dataStore=new Dictionary(); 公共无效插入(T dto),其中T:IDataTransferObject { if(!dataStore.ContainsKey(typeof(T))) { Add(typeof(T),newlist()); } 数据存储[类型(T)]。添加(dto); },c#,c#-4.0,covariance,contravariance,C#,C# 4.0,Covariance,Contravariance,上面的代码给了我数据存储上的编译错误。添加行是因为它不喜欢我尝试将列表分配给列表。既然我的方法将T限制为仅IDataTransferObject的,那么.NET4中的协方差/逆变的内容不应该允许此代码吗 我知道我可以把它改成新的列表,它会工作的,但我很好奇为什么原来的代码不工作。非常确定列表与列表不相关IEnumerable可能,但不能列出,因为您可以自由添加一个非T(但仍然IDataTransferObjects),它将引发运行时异常,以便在编译时捕获它 虽然您的代码在运行时可能是安全的(因为
列表
分配给列表
。既然我的方法将T限制为仅IDataTransferObject的,那么.NET4中的协方差/逆变的内容不应该允许此代码吗
我知道我可以把它改成新的列表
,它会工作的,但我很好奇为什么原来的代码不工作。非常确定列表
与列表
不相关IEnumerable
可能,但不能列出,因为您可以自由添加一个非T
(但仍然IDataTransferObjects
),它将引发运行时异常,以便在编译时捕获它
虽然您的代码在运行时可能是安全的(因为您按类型使用键),但编译器不知道这一点
private Dictionary<Type, List<IDataTransferObject>> dataStore = new Dictionary<Type, List<IDataTransferObject>>();
public void Insert<T>(T dto) where T : IDataTransferObject
{
if (!dataStore.ContainsKey(typeof(T)))
{
dataStore.Add(typeof(T), new List<T>());
}
dataStore[typeof(T)].Add(dto);
}
调用代码如下所示:
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(newpersondto());
插入(新的OrderDTO());
插入(新的PersonDTO());
List persons=Get();
List orders=Get();
控制台写入线(个人数)//2.
Console.WriteLine(orders.Count)//1.
因此,从外部来看,所有API的使用都是类型安全的。它不是一个列表(这意味着可以将非订单添加到对象),而是强类型的,不能混合和匹配
当然,在这一点上,没有必要约束到IDataTransferObject
,但这取决于您和您的API/设计/使用。也许您对版本号有点困惑?如果您指的是.NET4.5(C#5),那么有一个新接口,它的T
是协变的。请注意,在.NET中,只有接口(和委托类型)可以是协变的,而不是类/结构。IReadOnlyList
之所以可以成为协变的,是因为它只包含从基础列表读取的成员(无写入)。然而,IReadOnlyList
并不能帮助您解决“不可能”的问题,因此.NET4.5在这里毕竟没有帮助。
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