2009-09-01 15 views
10

Simple. Si utilizo:Usar pares clave-valor como parámetros

public void Add(params int[] values) 

Entonces puedo usar esto como:

Add(1, 2, 3, 4); 

Pero ahora estoy tratando con pares de clave y valor! Tengo una clase de KeyValue para vincular un número entero a un valor de cadena. Así que empiezo con:

public void Add(params KeyValue[] values) 

Pero no puedo usar esto:

Add(1, "A", 2, "B", 3, "C", 4, "D"); 

En cambio, me veo obligado a utilizar:

Add(new KeyValue(1, "A"), new KeyValue(2, "B"), new KeyValue(3, "C"), new KeyValue(4, "D")); 

Ewww ... Ya me gusta esto ...

Entonces, ahora uso la función Agregar sin el modificador de params y simplemente paso una matriz predefinida a esta función. Como solo se usa para una inicialización rápida para una prueba, no me preocupa demasiado la necesidad de este código adicional, aunque quiero que el código sea simple de leer. Me encantaría saber un truco para utilizar el método que no puedo usar, pero ¿hay alguna forma de hacerlo sin usar la nueva construcción "KeyValue()"?

+7

¿Sabía que ya hay un 'KeyValuePair '? –

+0

Sí, lo sé. :-) Es el tipo que uso ... –

Respuesta

23

Si ha aceptado una IDictionary<int,string>, usted podría utilizar probablemente (en C# 3.0, por lo menos):

Add(new Dictionary<int,string> { 
    {1, "A"}, {2, "B"}, {3, "C"}, {4, "D"} 
}); 

Cualquier uso?

Ejemplo Add:

static void Add(IDictionary<int, string> data) { 
    foreach (var pair in data) { 
     Console.WriteLine(pair.Key + " = " + pair.Value); 
    } 
} 
+0

¡Se ve bien! Mantiene las cosas en una línea. –

+0

También puede usar el aliasing tipo si no desea escribir todo el tipo de Diccionario genérico 'using Pairs = System.Collections.Generic.Dictionary ;' y luego usar como 'Add (new Pairs { {1," A "}, {2," B "}, {3," C "}, {4," D "} });' ligeramente más limpio. –

0

Usted podría utilizar algo como lo siguiente con el inconveniente obvio que usted suelta tipado fuerte.

public void Add(params Object[] inputs) 
{ 
    Int32 numberPairs = inputs.Length/2; 

    KeyValue[] keyValues = new KeyValue[numberPairs]; 

    for (Int32 i = 0; i < numberPairs; i++) 
    { 
     Int32 key = (Int32)inputs[2 * i]; 
     String value = (String)inputs[2 * i + 1]; 

     keyvalues[i] = new KeyValue(key, value); 
    } 

    // Call the overloaded method accepting KeyValue[]. 
    this.Add(keyValues); 
} 

public void Add(params KeyValue[] values) 
{ 
    // Do work here. 
} 

Usted debe de causa añadir un poco de manipulación si los argumentos son del tipo incorrecto de error. No es tan inteligente, pero funcionará.

3

Puede modificar su diseño de clase actual, pero deberá agregar genéricos y usar la interfaz IEnumerable.

class KeyValue<TKey, TValue> 
    { 
     public KeyValue() 
     { 
     } 
    } 

    // 1. change: need to implement IEnumerable interface 
    class KeyValueList<TKey, TValue> : IEnumerable<TKey> 
    { 
     // 2. prerequisite: parameterless constructor needed 
     public KeyValueList() 
     { 
      // ... 
     } 

     // 3. need Add method to take advantage of 
     // so called "collection initializers" 
     public void Add(TKey key, TValue value) 
     { 
      // here you will need to initalize the 
      // KeyValue object and add it 
     } 

     // need to implement IEnumerable<TKey> here! 
    } 

Después de estas adiciones se puede hacer lo siguiente:

new KeyValueList<int, string>() { { 1, "A" }, { 2, "B" } }; 

El compilador utilizará la interfaz IEnumerable y el método Add para poblar el KeyValueList. Tenga en cuenta que funciona para C# 3.0.

Si está utilizando esto para las pruebas, estos cambios no valen la pena. Es un gran esfuerzo y cambias bastante código de producción para las pruebas.

+1

Heredar de 'List >' y agregar el personalizado 'Add' sería la ruta más fácil aquí. –

+0

@Marc: Buena idea. No he pensado en eso. –

Cuestiones relacionadas