Пары значения ключа в C# Params

Я ищу способ иметь функцию, такую как:

myFunction({"Key", value}, {"Key2", value});

Я уверен, что существует что-то с анонимными типами, которые были бы довольно легки, но я не вижу его.

Единственное решение, о котором я могу думать, состоит в том, чтобы иметь a params KeyValuePair<String, object>[] pairs параметр, но это заканчивает тем, что было чем-то подобным:

myFunction(new KeyValuePair<String, object>("Key", value),
           new KeyValuePair<String, object>("Key2", value));

Который, по общему признанию, намного более ужасен.

Править:

Для разъяснения я пишу a Message класс для передачи между 2 различными системами. Это содержит a ushort определение Тип сообщения и словарь строки для возражения для "Данных", связанных с сообщением. Я хотел бы смочь передать всю эту информацию в конструкторе, таким образом, я могу сделать это:

Agent.SendMessage(new Message(MessageTypes.SomethingHappened, "A", x, "B", y, "C", z));

или подобный синтаксис.

32
задан Olivier Jacot-Descombes 5 August 2019 в 14:12
поделиться

6 ответов

Если синтаксис не соответствует нормальному шаблону, измените синтаксис. Как насчет:

public void MyFunction(params KeyValuePair<string, object>[] pairs)
{
    // ...
}

public static class Pairing
{
    public static KeyValuePair<string, object> Of(string key, object value)
    {
        return new KeyValuePair<string, object>(key, value);
    }
}

Использование:

MyFunction(Pairing.Of("Key1", 5), Pairing.Of("Key2", someObject));

Еще более интересным было бы добавить метод расширения к строке , чтобы сделать его сопоставляемым:

public static KeyValuePair<string, object> PairedWith(this string key, object value)
{
    return new KeyValuePair<string, object>(key, value);
}

Использование:

MyFunction("Key1".PairedWith(5), "Key2".PairedWith(someObject));

Изменить : Вы также можете используйте синтаксис словаря без общих скобок, производный от Dictionary <,> :

public void MyFunction(MessageArgs args)
{
    // ...
}

public class MessageArgs : Dictionary<string, object>
{}

Использование:

MyFunction(new MessageArgs { { "Key1", 5 }, { "Key2", someObject } });
62
ответ дан 27 November 2019 в 19:53
поделиться

Используйте Словарь ...

void Main()
{
    var dic = new Dictionary<string, object>();
    dic.Add( "Key1", 1 );
    dic.Add( "Key2", 2 );   

    MyFunction( dic ).Dump();
}

public static object MyFunction( IDictionary dic )
{
   return dic["Key1"];
}
2
ответ дан 27 November 2019 в 19:53
поделиться

Вот то же самое:

static void Main(string[] args)
{
    // http://msdn.microsoft.com/en-us/library/bb531208.aspx
    MyMethod(new Dictionary<string,string>()
    {
        {"key1","value1"},
        {"key2","value2"}
    });
}

static void MyMethod(Dictionary<string, string> dictionary)
{
    foreach (string key in dictionary.Keys)
    {
        Console.WriteLine("{0} - {1}", key, dictionary[key]);
    }
}

Некоторые подробности по инициализации словаря можно найти здесь .

2
ответ дан 27 November 2019 в 19:53
поделиться

Использование словаря:

myFunction(new Dictionary<string, object>(){
  {"Key", value}, 
  {"Key2", value}});

То есть вам нужен только один новый словарь , а не для каждого аргумента. Получить ключи и значения тривиально.

Или с анонимным типом:

myFunction(new {
  Key = value, 
  Key2 = value});

Что не очень удобно использовать внутри функции, вам понадобится отражение. Это выглядело бы примерно так:

foreach (PropertyInfo property in arg.GetType().GetProperties())
{
  key = property.Name;
  value = property.GetValue(arg, null);
}

(Прямо из головы, наверное, какие-то ошибки ...)

2
ответ дан 27 November 2019 в 19:53
поделиться

Забавно, я только что создал (несколько минут назад) метод, который позволяет делать это, используя анонимные типы и отражение:

MyMethod(new { Key1 = "value1", Key2 = "value2" });


public void MyMethod(object keyValuePairs)
{
    var dic = DictionaryFromAnonymousObject(keyValuePairs);
    // Do something with the dictionary
}

public static IDictionary<string, string> DictionaryFromAnonymousObject(object o)
{
    IDictionary<string, string> dic = new Dictionary<string, string>();
    var properties = o.GetType().GetProperties();
    foreach (PropertyInfo prop in properties)
    {
        dic.Add(prop.Name, prop.GetValue(o, null) as string);
    }
    return dic;
}
9
ответ дан 27 November 2019 в 19:53
поделиться

Это немного похоже на взлом, но вы можете сделать так, чтобы ваш класс Message реализовал интерфейс IEnumerable и дал ему метод Add . После этого вы сможете использовать синтаксис инициализатора коллекции:

Agent.SendMessage
(
    new Message(MessageTypes.SomethingHappened) {{ "foo", 42 }, { "bar", 123 }}
);

// ...

public class Message : IEnumerable
{
    private Dictionary<string, object> _map = new Dictionary<string, object>();

    public Message(MessageTypes mt)
    {
        // ...
    }

    public void Add(string key, object value)
    {
        _map.Add(key, value);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)_map).GetEnumerator();
        // or throw a NotImplementedException if you prefer
    }
}
7
ответ дан 27 November 2019 в 19:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: