2012-03-05 11 views
15

Duplicar posible:
Custom Collection InitializersCrear estilo Diccionario inicializador de colección de clase personalizada

Tengo una sencilla clase Par:

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

y nos gustaría poder para definirlo como un objeto de diccionario, todo en línea como tal:

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

Pero me pide que defina un nuevo par completo (0, "bob"), etc., ¿cómo implementaría esto?

Como de costumbre, gracias chicos!

+0

¡Buena pregunta! Edité tu respuesta para usar la terminología correcta (inicializador de recopilación). Esto generalmente se logra en el lado de la recopilación de cosas (tiene que tener un método Add()). En este caso, está usando una matriz por lo que no funciona del mismo modo. ¡Pero muy interesado en ver si hay formas de hacerlo funcionar! – MattDavey

+0

¿No eres fanático de 'KeyValuePair '? ¿O apostando por el conocimiento aplicado? –

Respuesta

17

Para obtener el inicialización personalizada para trabajar como diccionario que necesita para apoyar dos cosas. Su tipo necesita implementar IEnumerable y tener un método apropiado Add. Está inicializando un Array, que no tiene un método Add. Por ejemplo

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

y entonces usted puede hacer

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

¿Está sugiriendo que 'int [] nums = {1, 2, 3};' no es válido C#? porque es ... ¿Seguramente el problema es que Pair no tiene el método Add? – Chris

+0

@Chris Eso no es como el diccionario. –

+0

Sí, mirando más, veo dónde está el problema. Pensé que, dado que la sintaxis funciona como en mi comentario, el problema estaba en la generación del objeto Pair. Al mirar más cosas (e intentar escribir un código válido para hacer esto) me di cuenta de que la sintaxis utilizada por la publicación original intenta llamar a Agregar (1, "bob") en la matriz, que es lo que estabas diciendo que no t existe. Perdón por eso, pero dejaré el comentario para el próximo tonto pobre que piense como yo. :) – Chris

6

¿Por qué no utilizar una clase que hereda de Dictionary?

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

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

    Console.ReadKey(); 
} 

También puede crear su propia colección (sospecho que es el caso porque tiene el mismo Value1 por dos elementos, por lo T1 no actúa como una llave en su ejemplo) que no se heredan de Dictionary .

Si desea utilizar el azúcar sintáctica de inicializador de colección, que tendría que proporcionar un método que toma Add 2 argumentos (T1 y T2 que son int y string en su caso).

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

Ver Custom Collection Initializers

0

La sintaxis que está buscando no está prevista por el objeto que se utiliza con el diccionario, es la propia colección de diccionarios. Si necesita poder utilizar un inicializador de la colección , deberá usar una colección existente (como Dictionary) o implementar una colección personalizada para alojarla.

lo contrario que está básicamente limitado 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)); 
    } 
} 

y luego

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

va a funcionar. Básicamente, solo está creando una versión de List<Pair<T1,T2>> que sepa cómo hacer las cosas correctas Agregar cosas.

Esto es, obviamente, ampliable a cualquier otra clase que no sea Pair (de una manera que las soluciones de diccionario no lo son).

Gracias a Yuriy Faktorovich por ayudarme con mi comprensión inicial y la pregunta relacionada para señalarme en la dirección correcta.

+1

Lamento ser pedante, pero no necesitas 'foo', nunca lo usas. –

+0

Pedantería aprobada y corregida. Eso fue una resaca cuando estaba usando una lista como miembro en lugar de heredar. :) – Chris

Cuestiones relacionadas