なぜこのコードは「一般的なタイプ定義の不安」について不平を言うのでしょうか?

StackOverflow https://stackoverflow.com/questions/3765976

  •  04-10-2019
  •  | 
  •  

質問

一般的なタイプがあります:

class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>>

また、特定の辞書タイプのこのクラスのインスタンスを作成する(必要な)工場メソッド。

    private static IEqualityComparer<T> CreateDictionaryComparer<T>()
    {
        Type def = typeof(DictionaryComparer<,>);
        Debug.Assert(typeof(T).IsGenericType);
        Debug.Assert(typeof(T).GetGenericArguments().Length == 2);

        Type t = def.MakeGenericType(typeof(T).GetGenericArguments());

        return (IEqualityComparer<T>)Activator.CreateInstance(t);
    }

すべての無関係なものを取り除きます - このコードでさえ同じ例外をスローします。

private static object CreateDictionaryComparer()
{
    Type def = typeof(DictionaryComparer<,>);

    Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });

    return Activator.CreateInstance(t);
}

アサートはパスなので、私はそれを知っています T 一般的で、2つの一般的な引数があります。とのライン MakeGenericType ただし、以下を除きます

提供される一般的な引数の数は、一般的なタイプ定義の不安に等しくありません。

パラメーター名:インスタンス化

私は過去にこのようなことをしましたが、私の人生では、この場合にこれが機能しない理由を理解できません。 (さらに、Googleが必要でした アリティ).

役に立ちましたか?

解決

理解した。

私は持っていた DictionaryComparer 内部クラスとして宣言されています。私はそれを想定することしかできません MakeGenericType 作りたかった Query<T>.DictionaryComparer<string,object> 提供されませんでした T.

コードの障害

class Program
{
    static void Main(string[] args)
    {
        var q = new Query<int>();
        q.CreateError();
    }
}

public class Query<TSource>
{
    public Query()
    {    
    }

    public object CreateError()
    {
        Type def = typeof(DictionaryComparer<,>);

        Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });

        return Activator.CreateInstance(t);
    }

    class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>>
    {
        public DictionaryComparer()
        {
        }

        public bool Equals(IDictionary<TKey, TValue> x, IDictionary<TKey, TValue> y)
        {
            if (x.Count != y.Count)
                return false;

            return GetHashCode(x) == GetHashCode(y);
        }

        public int GetHashCode(IDictionary<TKey, TValue> obj)
        {
            int hash = 0;
            unchecked
            {
                foreach (KeyValuePair<TKey, TValue> pair in obj)
                {
                    int key = pair.Key.GetHashCode();
                    int value = pair.Value != null ? pair.Value.GetHashCode() : 0;
                    hash ^= key ^ value;
                }
            }
            return hash;
        }
    }
}

他のヒント

CLRは、アプリケーションで使用されているすべてのタイプの内部データ構造を作成します。これらのデータ構造は、タイプオブジェクトと呼ばれます。汎用型パラメーターを持つタイプはオープンタイプと呼ばれ、 CLRは、オープンタイプのインスタンスを構築することを許可していません (CLRがインターフェイスタイプのインスタンスが構築されるのを防ぐ方法と同様)。

変化する

Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });

Type t = def.MakeGenericType(new Type[] { typeof(TSource), typeof(String), typeof(object) });
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top