2009-09-01 20 views
10

Prosta. Jeśli używam:Używanie par klucz-wartość jako parametrów

public void Add(params int[] values) 

Wtedy mogę to wykorzystać jako:

Add(1, 2, 3, 4); 

Ale teraz mam do czynienia z par klucz-wartość! Mam klasę KeyValue, aby połączyć liczbę całkowitą z wartością ciągu. Więc zacznę:

public void Add(params KeyValue[] values) 

Ale nie mogę użyć tego:

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

Zamiast tego, jestem zmuszony do korzystania:

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

Ewww ... Już Nie lubię to ...

Tak, teraz używam funkcji Dodaj bez modyfikatora params i po prostu przekazuję predefiniowaną tablicę do tej funkcji. Ponieważ jest używany tylko do szybkiej inicjalizacji testu, nie martwię się zbytnio o ten dodatkowy kod, chociaż chcę, aby kod był łatwy do odczytania. Chciałbym znać sztuczkę, aby użyć metody, której nie mogę użyć, ale czy jest jakiś sposób, aby to zrobić bez użycia "nowej konstrukcji KeyValue()"?

+7

Wiesz, że istnieje już 'KeyValuePair '? –

+0

Tak, wiem. :-) To jest typ, którego używam ... –

Odpowiedz

23

Jeśli przyjął IDictionary<int,string>, można przypuszczalnie użyć (w języku C# 3.0, przynajmniej):

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

Jakiekolwiek użycie?

Przykład Add:

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

Wygląda dobrze! Utrzymuje rzeczy w jednej linii. –

+0

Możesz również użyć aliasu typu, jeśli nie chcesz wypisać całego ogólnego słownika typu 'using Pairs = System.Collections.Generic.Dictionary ;' a następnie użyć jako 'Dodaj (nowe pary { {1,") A "}, {2," B "}, {3," C "}, {4," D "} });" nieco schludniej. –

0

Można użyć coś jak następuje z oczywistą wadę, że tracisz silną wpisywanie.

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

Powinieneś dodać trochę błędów, jeśli argumenty są niepoprawnego typu. Nie takie mądre, ale zadziała.

3

Możesz modyfikować swój obecny projekt klasy, ale będziesz musiał dodać generyczne i użyć interfejsu 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! 
    } 

Po tych dodatków można wykonać następujące czynności:

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

Kompilator będzie korzystał z interfejsu IEnumerable i metody Add, aby wypełnić KeyValueList. Zauważ, że działa dla C# 3.0.

Jeśli używasz tego do testów, te zmiany nie są tego warte. To duży wysiłek i zmieniasz sporo kodu produkcyjnego do testów.

+1

Dziedziczenie z 'List >' i dodanie niestandardowego 'Add' byłoby tutaj najprostszą trasą. –

+0

@Marc: Dobry pomysł. Nie pomyślałem o tym. –

Powiązane problemy