在Dictionary <t1,someenum>和Dictionary <t3,someenum>之间转换,其中T1:T3引发错误</t3,someenum> </t1,someenum>

时间:2015-01-24 22:30:16

标签: c# .net generics dictionary collections

我有以下代码(这些名称仅用于示例目的):

一些以字典形式提供数据的函数:

public Dictionary<IMayor, SocialStatus> GetMayorSocialStatuses()
{
    //Do Stuff
}

public Dictionary<IJanitor, SocialStatus> GetJanitorSocialStatuses()
{
    //Do Stuff
}

然后我尝试将这些结果添加到IPerson类型的字典中。

IJanitorIMayor都实施IPerson

假设我没有问题,我试图做以下事情:

public Dictionary<IPerson,SocialStatus> GetPersonsSocialStatuses()
{
    var dict=new Dictionary<IPerson,S ocialStatus>();

    foreach(var mayorKvp in GetMayorSocialStatuses())
    {
        dict.Add(mayorKvp.Key,mayorKvp.Value);
    }

    foreach(var janitorKvp in GetJanitorSocialStatuses())
    {
        dict.add(janitorKvp.Key,janitorKvp.Value);
    }
}

像魅力一样工作,但是foreach看起来像是在冒险。

我尝试用此扩展方法替换它们:

public static Dictionary<IPerson,SocialStatus> AddRange(
                            this Dictionary<IPerson,SocialStatus> dict, 
                            Dictionary<IPerson,SocialStatus> inputDict)
{
     foreach(var kvp in inputDict)
     {
         dict.add(kvp.Key,kvp.Value);
     }

     return dict;;
}

但是通过这样做,我收到了一个编译错误,它无法从IMayor,SocialStatus类型的字典转换为IPerson,SocialStatus

在调查这个问题之后,我意识到它们不是可浇铸的,因为这种方式称为&#34;关闭泛型类型&#34;这意味着继承不会移动到字典中,也无法进行转换。

问题是:我该如何解决问题?

有没有更清洁的方法呢?

(因为如果提供者不在同一个班级/静态班级,我就被搞砸了)

我没有绑定到特定版本的.NET,所以任何解决方案都会很棒。

1 个答案:

答案 0 :(得分:3)

编译错误是正确的 - 您不能将具体类型的字典(使用一种类型的键参数化)分配给另一种,不同(使用其他键类型) - 类型不匹配(如您所述)。 一种可能的解决方案是将扩展方法参数更改为接受IDictionary作为参数。不幸的是,它也无济于事 - 因为接口是参数化不变的(convariance and contravariance)。

可能的解决方案:

public static Dictionary<IPerson, string> AddRange<TPerson>(
                    this Dictionary<IPerson, string> dict, 
                    Dictionary<TPerson, string> inputDict)
    where TPerson : IPerson
{
    foreach (var kvp in inputDict)
    {
        dict.Add(kvp.Key, kvp.Value);
    }

    return dict;
}