C# さん C#、あなたは何で推論してくれないの orz

public static D safeAdd<D, C, K, V>(D map, K key, V value)
    where C : ICollection<V>, new()
    where D : IDictionary<K, C>
{
    C list;
    if (!map.TryGetValue(key, out list))
    {
        list = new C();
        map.Add(key, list);
    }
    list.Add(value);
    return map;
}

C# *1 で少しメタメタな関数作って呼び出そうと思ったんですよ。


Dictionary<string, List<string> > map = new Dictionary<string,List<string> >();

// CS0411:
// メソッド 'safeAdd<D,C,K,V>(D, K, V)' に対する
// 型引数を使い方から推論することはできません。
// 型引数を明示的に指定してください。
safeAdd(map, "金糸雀", "かなりあ");

// OK
safeAdd<Dictionary<string, List<string> >,
    List<string>, string, string>(map, "金糸雀", "カナリア");

なんで推論してくれないのかしら… orz

なんか指定が足りないのかしら…




multiset が有れば今やってるヤツには満足できるんだけどなぁー(ぉ


ちなみに

Dictionary だけ妥協すると上記の呼び出しコードは通るようになります。 Dictionary 周りででなんかあるんでしょうけど…なんだろうなぁ…

// コレだと呼び出しコードが両方通る
public static Dictionary<K, C> safeAdd<C, K, V>(Dictionary<K, C> map, K key, V value)
    where C : ICollection<V>, new()
{
    C list;
    if (!map.TryGetValue(key, out list))
    {
        list = new C();
        map.Add(key, list);
    }
    list.Add(value);
    return map;
}

追記 16:40

書いてから気づいた。

別に Dictionary の部分 generic にせずに IDictionary 受ける形にすれば今回の用途じゃ満足じゃん。何してるの俺(ぉ orz

public static IDictionary<K, C> safeAdd<C, K, V>(IDictionary<K, C> map, K key, V value);

*1:2008 / .NET Framework 2.0 プロジェクト