2010-09-22 10 views
11

Ho un tipo generico:Perché questo codice si lamenta di "l'arità della definizione del tipo generico"?

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

E un metodo factory che (dovrebbe) creare un'istanza di questa classe per un determinato tipo di dizionario.

Strippare tutte le cose estranee - anche questo codice genera la stessa eccezione.

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

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

    return Activator.CreateInstance(t); 
} 

Il asserisce passo quindi so che T è generica e ha due argomenti generici. La riga con MakeGenericType tuttavia esclude con:

Il numero di argomenti generici forniti non corrisponde all'arità della definizione di tipo generico.

Nome di parametro: instanziazione

ho fatto questo genere di cose in passato e per la vita di me non riesco a capire il motivo per cui questo non sta funzionando in questo caso. (Inoltre ho dovuto Google arity).

+0

Cosa stai passando come 'T' a' CreateDictionaryComparer'? Ho provato a passare 'CreateDictionaryComparer >()' e questo funziona bene per me (usando il compilatore Mono C# versione 1.9.1.0). –

+0

Avevo DictionaryComparer come classe interna a uno che è esso stesso generico. Pensa che stia perdendo i lavori. – dkackman

+0

Solo per curiosità, potresti fornire il campione completo (in mancanza) in modo che possa provarlo sul mio compilatore? –

risposta

13

Capito.

Avevo DictionaryComparer dichiarato come classe interiore. Posso solo supporre che MakeGenericType volesse creare un Query<T>.DictionaryComparer<string,object> e non sia stato fornito T.

mancanza codice

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

Solo per curiosità, potresti fornire il campione completo (in mancanza) in modo che possa provarlo sul mio compilatore? –

+0

Lemme, vedi se riesco a rimuovere materiale non correlato in un esempio compilabile – dkackman

+0

Grazie! Lo spostamento di 'DictionaryComparer ' al di fuori della classe del contenitore generico 'Query ' risolve il problema. Ho sperimentato e tu puoi annidare 'DictionaryComparer ', solo non all'interno di un'altra classe generica. Volevo anche assicurarmi che il mio compilatore e l'ambiente di runtime si comportassero come i tuoi. –

1

CLR crea una struttura dati interna per ogni tipo in uso da un application.These strutture dati sono chiamati oggetti di tipo. Un tipo con parametri di tipo generico viene definito di tipo aperto e il CLR non consente di creare un'istanza di tipo aperto (analogamente a come il CLR impedisce l'esecuzione di un'istanza di un tipo di interfaccia).

Modifica Tipo t = def.MakeGenericType (new Type [] {typeof (String), typeof (oggetto)});
sul
Type t = def.MakeGenericType (nuovo tipo [] {typeof (TSource), typeof (String), typeof (oggetto)});

Problemi correlati