在 Dictionary<T1,someEnum> 和 Dictionary<T3,someEnum> 之间转换,其中 T1:T3 抛出错误
cast between Dictionary<T1,someEnum> and Dictionary<T3,someEnum> where T1:T3 Throws an Error
我有以下代码(名称仅供示例):
一些将数据作为字典提供给我的函数:
public Dictionary<IMayor, SocialStatus> GetMayorSocialStatuses()
{
//Do Stuff
}
public Dictionary<IJanitor, SocialStatus> GetJanitorSocialStatuses()
{
//Do Stuff
}
然后我尝试将这些结果添加到 IPerson
.
类型的字典中
IJanitor
和 IMayor
都实现了 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
。
调查问题后,我意识到由于一种称为 "close generic type" 的方式,它们不可转换,这意味着继承不会移动到字典中,因此无法进行转换。
问题是:那我该如何解决呢?
没有更简洁的方法吗?
(因为如果提供商不在同一个 class/a 静态 class 中,我就完蛋了)
我没有绑定到特定版本的 .NET,所以任何解决方案都很好。
编译器错误是正确的 - 您不能将具体类型的字典(使用一种类型的键参数化)分配给另一个不同的(使用其他类型的键)- 类型不匹配(如您所述)。
一种可能的解决方案是更改扩展方法参数以接受 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;
}
我有以下代码(名称仅供示例):
一些将数据作为字典提供给我的函数:
public Dictionary<IMayor, SocialStatus> GetMayorSocialStatuses()
{
//Do Stuff
}
public Dictionary<IJanitor, SocialStatus> GetJanitorSocialStatuses()
{
//Do Stuff
}
然后我尝试将这些结果添加到 IPerson
.
IJanitor
和 IMayor
都实现了 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
。
调查问题后,我意识到由于一种称为 "close generic type" 的方式,它们不可转换,这意味着继承不会移动到字典中,因此无法进行转换。
问题是:那我该如何解决呢?
没有更简洁的方法吗?
(因为如果提供商不在同一个 class/a 静态 class 中,我就完蛋了)
我没有绑定到特定版本的 .NET,所以任何解决方案都很好。
编译器错误是正确的 - 您不能将具体类型的字典(使用一种类型的键参数化)分配给另一个不同的(使用其他类型的键)- 类型不匹配(如您所述)。
一种可能的解决方案是更改扩展方法参数以接受 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;
}