¿Por qué este código se quejan de “la aridad de la definición de tipo genérico”?

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

  •  04-10-2019
  •  | 
  •  

Pregunta

Tengo un tipo genérico:

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

Y un método de fábrica que (debe) crear una instancia de esta clase para un tipo de diccionario dado.

    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);
    }

quitando toda la materia extraña -. Incluso este código produce la misma excepción

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

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

    return Activator.CreateInstance(t);
}

El Afirma pase, así que sé que T es genérico y tiene dos argumentos genéricos. La línea con MakeGenericType sin embargo excepts con:

El número de argumentos genéricos proporcionado no es igual a la aridad de la definición de tipo genérico.

Nombre de parámetro: ejemplificación

he hecho este tipo de cosas en el pasado y por la vida de mí, no puede entender por qué esto no está funcionando en este caso. (Además de que tenía que Google aridad ).

¿Fue útil?

Solución

descubierto.

tuve DictionaryComparer declara como una clase interna. Sólo puedo suponer que MakeGenericType quería hacer una Query<T>.DictionaryComparer<string,object> y no se proporcionó T.

A falta de código

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;
        }
    }
}

Otros consejos

CLR crea una estructura de datos interna para todos y cada tipo en uso por un estructuras de datos application.These son llamados objetos de tipo. Un tipo con parámetros de tipo genérico se llama un tipo abierto, y el CLR no permite cualquier instancia de un tipo abierto para ser construido (similar a cómo el previene CLR una instancia de un tipo de interfaz de ser construidos ).

Cambiar

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

en

Type t = def.MakeGenericType(new Type[] { typeof(TSource), typeof(String), typeof(object) });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top