2012-03-05 10 views
15

Eventuali duplicati:
Custom Collection InitializersCrea Dizionario stile raccolta inizializzatore sulla classe personalizzata

Ho una semplice classe Coppia:

public class Pair<T1, T2> 
    { 
     public Pair(T1 value1, T2 value2) 
     { 
      Value1 = value1; 
      Value2 = value2; 
     } 

     public T1 Value1 { get; set; } 
     public T2 Value2 { get; set; } 
    } 

e vorrebbe essere in grado per definirlo come un oggetto dizionario, tutto in linea in questo modo:

var temp = new Pair<int, string>[] 
     { 
      {0, "bob"}, 
      {1, "phil"}, 
      {0, "nick"} 
     }; 

Ma mi sta chiedendo di definire una coppia completamente nuova (0, "bob") ecc., Come potrei implementarla?

Come al solito, grazie ragazzi!

+0

Buona domanda! Ho modificato la tua risposta per utilizzare la terminologia corretta (inizializzatore della raccolta). Questo di solito si realizza sul lato della collezione di cose (deve avere un metodo Add()). In questo caso stai usando un array in modo che non funzioni allo stesso modo. Ma molto interessato a vedere se ci sono modi per farlo funzionare! – MattDavey

+0

Non è un fan di 'KeyValuePair '? O andando per la conoscenza applicata? –

risposta

17

Per ottenere l'inizializzazione personalizzato per funzionare come dizionario è necessario supportare due cose. Il tuo tipo deve implementare IEnumerable e avere un metodo appropriato Add. Si sta inizializzando un Array, che non ha un metodo Add. Per esempio

class PairList<T1, T2> : IEnumerable 
{ 
    private List<Pair<T1, T2>> _list = new List<Pair<T1, T2>>(); 

    public void Add(T1 arg1, T2 arg2) 
    { 
     _list.Add(new Pair<T1, T2>(arg1, arg2)); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 
} 

e allora si può fare

var temp = new PairList<int, string> 
{ 
    {0, "bob"}, 
    {1, "phil"}, 
    {0, "nick"} 
}; 
+0

Stai suggerendo che 'int [] nums = {1, 2, 3};' non è valido C#? perché è ... Sicuramente il problema è che Pair non ha il metodo Add? – Chris

+0

@Chris Questo non è come un dizionario. –

+0

Sì, guardando di più vedo dove si trova il problema. Avevo pensato che dal momento che la sintassi funziona come nel mio commento, il problema era con la generazione dell'oggetto Pair. Guardando più cose (e tentando di scrivere codice valido per farlo) mi sono reso conto che la sintassi usata dal post originale sta cercando di chiamare Add (1, "bob") sull'array che è quello che stavi dicendo non fa Esistono Mi dispiace, lascerò il commento per il prossimo povero pazzo a pensare come me. :) – Chris

6

Perché non utilizzare una classe che eredita da?

public class PairDictionary : Dictionary<int, string> 
{ 
} 

private static void Main(string[] args) 
{ 
    var temp = new PairDictionary 
    { 
     {0, "bob"}, 
     {1, "phil"}, 
     {2, "nick"} 
    }; 

    Console.ReadKey(); 
} 

Si potrebbe anche creare la propria collezione (ho il sospetto che è il caso, perché si ha la stessa Value1 per due elementi, in modo da T1 non agisce come una chiave nel tuo esempio) che non eredita da Dictionary .

Se si desidera utilizzare lo zucchero sintattico della raccolta di inizializzazione, si dovrebbe fornire un metodo Add che prende 2 argomenti (T1 e T2 che sono int e string nel tuo caso).

public void Add(int value1, string value2) 
{ 
} 

Vedi Custom Collection Initializers

0

La sintassi che stai cercando non è prevista dall'oggetto che viene utilizzato con il dizionario, è la collezione dizionario stesso. Se è necessario essere in grado di utilizzare un inizializzatore della raccolta , sarà necessario utilizzare una raccolta esistente (come Dizionario) o implementare una raccolta personalizzata per ospitarla.

altrimenti sei fondamentalmente limitato a:

var temp = new Pair<int, string>[] 
    { 
     new Pair(0, "bob"), 
     new Pair(1, "phil"), 
     new Pair(0, "nick") 
    }; 
2
public class Paircollection<T1, T2> : List<Pair<T1, T2>> 
{ 
    public void Add(T1 value1, T2 value2) 
    { 
     Add(new Pair<T1, T2>(value1, value2)); 
    } 
} 

e poi

var temp = new Paircollection<int, string> 
{ 
    {0, "bob"}, 
    {1, "phil"}, 
    {0, "nick"} 
}; 

funzionerà. Essenzialmente stai solo creando una versione di List<Pair<T1,T2>> che sa come fare le cose giuste Aggiungi.

Ovviamente è espandibile su qualsiasi altra classe rispetto a Pair (in modo diverso dalle soluzioni dizionario).

Grazie a Yuriy Faktorovich per avermi aiutato con la mia comprensione iniziale e la domanda collegata per avermi indicato nella giusta direzione.

+1

Mi spiace essere pedante, ma non hai bisogno di 'pippo', non lo usi mai. –

+0

Pedanteria approvata e corretta. Era una sbornia quando stavo usando una lista come membro piuttosto che ereditare. :) – Chris

Problemi correlati