Warum würden sich beschweren dieser Code über „die arity der generischen Typdefinition“?
-
04-10-2019 - |
Frage
Ich habe eine generische Art bekommen:
class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>>
Und eine Factory-Methode, die wird (soll) eine Instanz dieser Klasse für einen bestimmten Wörterbuchtyp erstellen.
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);
}
Stripping alle der Fremd Sachen weg -. Auch diesen Code führt die gleiche Ausnahme
private static object CreateDictionaryComparer()
{
Type def = typeof(DictionaryComparer<,>);
Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });
return Activator.CreateInstance(t);
}
Der Pass Asserts damit ich weiß, dass T
generisch ist und hat zwei generische Argumente. Die Linie mit MakeGenericType
jedoch excepts mit:
Die Anzahl der generischen Argumente vorgesehen ist gleich nicht die arity der generischen Typdefinition.
Parametername: Instanziierung
Ich habe diese Art der Sache in der Vergangenheit getan und für das Leben von mir kann nicht herausfinden, warum dies in diesem Fall nicht funktioniert. (Plus ich Google hatte arity ).
Lösung
es herausgefunden.
Ich hatte DictionaryComparer
als innere Klasse deklariert. Ich kann nur annehmen, dass MakeGenericType
eine Query<T>.DictionaryComparer<string,object>
machen wollte und nicht T
zur Verfügung gestellt.
Failing Code
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;
}
}
}
Andere Tipps
CLR erstellt eine interne Datenstruktur für jeden Typ in Verwendung durch eine application.These Datenstrukturen werden Objekte vom Typ genannt. Ein Typ mit generischen Typparametern ist ein offener Typ genannt, und die CLR ermöglicht keine Instanz eines offenen Typs konstruiert werden (ähnlich wie die CLR verhindert, dass eine Instanz einer Schnittstelle Typ so konstruiert ).
Ändern
Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) });
auf
Type t = def.MakeGenericType(new Type[] { typeof(TSource), typeof(String), typeof(object) });