Использование пар ключ-значение в качестве параметров
Simple. Если я использую:
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"));
Ewww... Мне уже не нравится...
Итак, прямо сейчас я использую функцию Add без модификатора params и просто передаю предварительно определенную массив этой функции. Поскольку он просто использовался для быстрой инициализации теста, я не слишком беспокоюсь о необходимости использования этого дополнительного кода, хотя я хочу, чтобы код был прост для чтения. Я хотел бы знать трюк, чтобы использовать метод, который я не могу использовать, но есть ли способ сделать это, не используя конструкцию "new KeyValue()?
Ответы
Ответ 1
Если вы приняли IDictionary<int,string>
, вы, вероятно, можете использовать (по крайней мере, в С# 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);
}
}
Ответ 2
Вы можете изменить текущий дизайн вашего класса, но вам нужно будет добавить generics и использовать интерфейс 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. Обратите внимание, что он работает для С# 3.0.
Если вы используете это для тестов, эти изменения не стоят того. Это довольно сложно, и вы меняете довольно много производственного кода для тестов.
Ответ 3
Вы можете использовать что-то вроде следующего с очевидным недостатком, что вы потеряете сильную типизацию.
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.
}
Вы должны вызвать некоторую ошибку, если аргументы неправильного типа. Не тот умный, но он будет работать.