63

IDictionary<TKey, TValue>.NET 4 / Silverlight 4 では共分散がサポートされていません。

IDictionary<string, object> myDict = new Dictionary<string, string>();

s で今できることと類似していIEnumerable<T>ます。

おそらくKeyValuePair<TKey, TValue>共変ではないことにも要約されます。少なくとも値については、辞書で共分散を許可する必要があると思います。

それで、それはバグですか、それとも機能ですか?おそらく .NET 37.4 で実現するのでしょうか?

更新(2年後):

IReadOnlyDictionary<TKey, TValue>.NET 4.5 には がありますが、共変にはなりません。:·/これは から派生したものであり、インターフェイスではないため、IEnumerable<KeyValuePair<TKey, TValue>>KeyValuePair<TKey, TValue>変にはなりません。

BCL チームは、代わりにいくつかを使用するために、多くを再設計する必要がありますICovariantPair<TKey, TValue>。また、厳密に型指定されたインデクサーthis[TKey key]などは、共変インターフェイスでは使用できません。GetValue<>(this IReadOnlyDictionary<TKey, TValue> self, TKey key)同様の目的は、実際の実装を内部的に呼び出さなければならない拡張メソッドをどこかに配置することによってのみ達成できます。これは、間違いなく非常に面倒なアプローチのように見えます。

4

6 に答える 6

5

同様の問題がありましたが、より特殊化された派生型 (すべてが派生するオブジェクトではなく) を使用していました

秘訣は、メソッドをジェネリックにして、関連する制限を入れる 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-10-31T10:12:10.553 に答える