使用键值对作为参数

11

简单。如果我使用:

public void Add(params int[] values)

然后我可以这样使用:

Add(1, 2, 3, 4);

但是现在我要处理键值对!我有一个KeyValue类来将整数链接到字符串值。所以我从以下内容开始:

public void Add(params KeyValue[] values)

但是我不能使用这个:

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

相反,我被迫使用:

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

噁心...我已经不喜欢这个了...

所以,现在我使用Add函数而没有使用params修饰符,只是将一个预定义的数组传递给这个函数。由于它只用于测试的快速初始化,我并不太担心需要这个额外的代码,尽管我想保持代码简单易读。我想知道有没有诀窍可以使用我不能使用的方法,但是否有不使用"new KeyValue()"构造的方法呢?


7
你知道已经有一个 KeyValuePair<TKey, TValue> 了吗? - Joel Coehoorn
是的,我知道。 :-) 这是我使用的类型... - Wim ten Brink
3个回答

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

如果您不想输入整个泛型字典类型,也可以使用类型别名。例如:using Pairs = System.Collections.Generic.Dictionary<int, string>; 然后使用 Add(new Pairs { {1, "A"}, {2, "B"}, {3, "C"}, {4, "D"} }); 会更加简洁明了。 - Adam Naylor

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

编译器将使用IEnumerable接口和Add方法来填充KeyValueList。请注意,它适用于C# 3.0。
如果您仅用于测试,则这些更改并不值得。为了进行测试,这需要相当大的努力,并且您需要更改大量的生产代码。

1
继承自 List<KeyValue<TKey, TValue>> 并添加自定义的 Add 方法将是最简单的路线。 - Marc Gravell
@Marc:好主意。我没想到过。 - Theo Lenndorff

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

如果参数类型不正确,你当然应该添加一些错误处理。虽然不是很聪明,但它会起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接