Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不应该';变异协方差/逆变换在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 - Fatal编程技术网

不应该';变异协方差/逆变换在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