Warum würden sich beschweren dieser Code über „die arity der generischen Typdefinition“?

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

  •  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 ).

War es hilfreich?

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) });
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top