なぜこのコードは「一般的なタイプ定義の不安」について不平を言うのでしょうか?
-
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) });
所属していません StackOverflow