.NET 4/Silverlight4中的IDictionary<TKey, TValue>
不支持协方差,即我不能
IDictionary<string, object> myDict = new Dictionary<string, string>();
类似于我现在可以使用IEnumerable<T>
%s执行的操作。
可能归结为KeyValuePair<TKey, TValue>
也不是协变的。我觉得在字典中应该允许协方差,至少对于值是允许的。
那么,这是一个bug还是一个特性?它会出现吗,也许是在.NET 37.4中?
更新(两年后):
在.NET 4.5中会有一个IReadOnlyDictionary
,但它也不会是协变的:·/
,因为它是从IEnumerable<KeyValuePair<TKey, TValue>>
派生的,而KeyValuePair<TKey, TValue>
不是一个接口,因此不能是协变的。
BCL团队将不得不重新设计很多东西,才能使用一些ICovariantPair<TKey, TValue>
。此外,强类型索引器ála this[TKey key]
不可能用于协变接口。类似的目的只能通过将扩展方法GetValue<>(this IReadOnlyDictionary<TKey, TValue> self, TKey key)
放在某个地方来实现,该扩展方法在内部必须以某种方式调用实际的实现,这看起来似乎是一种相当混乱的方法。
发布于 2014-10-31 18:12:11
我也有类似的问题,但是使用了更专业的派生类型(而不是所有东西都派生自的object )
诀窍是使方法泛型,并在where子句中添加相关的限制。假设您正在处理基类型和派生类型,下面的工作:
using System;
using System.Collections.Generic;
namespace GenericsTest
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
private void Run()
{
Dictionary<long, SpecialType1> a = new Dictionary<long, SpecialType1> {
{ 1, new SpecialType1 { BaseData = "hello", Special1 = 1 } },
{ 2, new SpecialType1 { BaseData = "goodbye", Special1 = 2 } } };
Test(a);
}
void Test<Y>(Dictionary<long, Y> data) where Y : BaseType
{
foreach (BaseType x in data.Values)
{
Console.Out.WriteLine(x.BaseData);
}
}
}
public class BaseType
{
public string BaseData { get; set; }
}
public class SpecialType1 : BaseType
{
public int Special1 { get; set; }
}
}
发布于 2014-04-02 23:21:12
IDictionary
上特定类型的有用协方差的变通方法
public static class DictionaryExtensions
{
public static IReadOnlyDictionary<TKey, IEnumerable<TValue>> ToReadOnlyDictionary<TKey, TValue>(
this IDictionary<TKey, List<TValue>> toWrap)
{
var intermediate = toWrap.ToDictionary(a => a.Key, a => a.Value!=null ?
a.Value.ToArray().AsEnumerable() : null);
var wrapper = new ReadOnlyDictionary<TKey, IEnumerable<TValue>>(intermediate);
return wrapper;
}
}
发布于 2021-10-25 16:22:36
假设您只需要一个字典中的特定操作,您可以创建一个包装器:
class Container
{
private IDictionary<string, string> myDict = new Dictionary<string, string>();
public object GetByKey(string key) => myDict[key];
}
或者甚至在Container中实现所需的接口。
https://stackoverflow.com/questions/2149589
复制相似问题