2009-09-01 18 views
10

シンプル。私が使用している場合:キーと値のペアをパラメータとして使用する

public void Add(params int[] values) 

それから私は、としてこれを使用することができます。

Add(1, 2, 3, 4); 

しかし、今、私は、キーと値のペアを扱っています!私は文字列値に整数をリンクするKeyValueクラスを持っています。だから私はで始まる:

public void Add(params KeyValue[] values) 

しかし、私はこれを使用することはできません。

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

Ewwwが...すでに私が嫌い:代わりに

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

を、私が使用するように強制していますthis ...

今、私はparams修飾子なしでAdd関数を使い、あらかじめ定義された配列をこの関数に渡します。テストのための迅速な初期化に使用されているだけなので、コードをシンプルにしておきたいのですが、私はこの追加のコードを必要とすることにあまり心配していません。私は使用できないメソッドを使用するトリックを知りたいですが、 "新しいKeyValue()"構造を使用せずにこれを行う方法はありますか?

+7

「KeyValuePair 」は既にありますか? –

+0

ええ、私は知っています。 :-)それは私が使用しているタイプです... –

答えて

23

あなたがIDictionary<int,string>を受け入れた場合、あなたはおそらく(少なくともC#3.0で)使用することもできます

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

どれでも使用することを?

Add

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

いいね!物事を1行に収めています。 –

+0

また、ジェネリックディクショナリタイプの 'Pairs = System.Collections.Generic.Dictionary ; 'を使用しないで、' Add(new Pairs { {1、 A "}、{2、" B "}、{3、" C "}、{4、" D "} }); –

0

あなたは強い型付けを失う明らかな欠点で、次のようなものを使用することができます。

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

引数の型が正しくない場合、エラー処理を追加する必要があります。それは賢明ではありませんが、うまくいくでしょう。

3

現在のクラスデザインは変更できますが、ジェネリックを追加して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! 
    } 

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

コンパイラはKeyValueListを移入するIEnumerableインターフェイスとAddメソッドを使用します。 C#3.0では動作することに注意してください。

これをテストに使用している場合、これらの変更は価値がありません。それはかなりの努力であり、あなたはテストのためのかなり多くの生産コードを変更します。

+1

'List >'から継承し、カスタム 'Add 'を追加すると、ここで最も簡単なルートになります。 –

+0

@Marc:良いアイデア。それを考えなかった。 –

関連する問題