首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >IDictionary<TKey,.NET 4中的TValue>不是协变的

IDictionary<TKey,.NET 4中的TValue>不是协变的
EN

Stack Overflow用户
提问于 2010-01-28 03:04:52
回答 3查看 9K关注 0票数 63

.NET 4/Silverlight4中的IDictionary<TKey, TValue>不支持协方差,即我不能

代码语言:javascript
复制
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)放在某个地方来实现,该扩展方法在内部必须以某种方式调用实际的实现,这看起来似乎是一种相当混乱的方法。

EN

回答 3

Stack Overflow用户

发布于 2014-10-31 18:12:11

我也有类似的问题,但是使用了更专业的派生类型(而不是所有东西都派生自的object )

诀窍是使方法泛型,并在where子句中添加相关的限制。假设您正在处理基类型和派生类型,下面的工作:

代码语言:javascript
复制
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; }
}
}
票数 5
EN

Stack Overflow用户

发布于 2014-04-02 23:21:12

IDictionary上特定类型的有用协方差的变通方法

代码语言:javascript
复制
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;
    }   
}
票数 0
EN

Stack Overflow用户

发布于 2021-10-25 16:22:36

假设您只需要一个字典中的特定操作,您可以创建一个包装器:

代码语言:javascript
复制
class Container
{
    private IDictionary<string, string> myDict = new Dictionary<string, string>();

    public object GetByKey(string key) => myDict[key];
}

或者甚至在Container中实现所需的接口。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2149589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档