C#参数中的键值对

Qua*_*ion 32 c# parameters key-value

我正在寻找一种方法来获得如下功能:

myFunction({"Key", value}, {"Key2", value});
Run Code Online (Sandbox Code Playgroud)

我确定有一些匿名类型的东西很容易,但我没有看到它.

我能想到的唯一解决方案是使用"params KeyValuePair [] pairs"参数,但最终会出现类似于:

myFunction(new KeyValuePair<String, object>("Key", value),
           new KeyValuePair<String, object>("Key2", value));
Run Code Online (Sandbox Code Playgroud)

诚然,这更加丑陋.

编辑:

为了澄清,我正在写一个"消息"类来传递两个不同的系统.它包含指定消息类型的ushort,以及与消息关联的"Data"的字符串到对象的字典.我希望能够在构造函数中传递所有这些信息,所以我能够这样做:

Agent.SendMessage(新消息(MessageTypes.SomethingHappened,"A",x,"B",y,"C",z)); 或类似的语法.

Bry*_*tts 62

如果语法不适合其他方面的模式,请更改语法.怎么样:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

MyFunction(Pairing.Of("Key1", 5), Pairing.Of("Key2", someObject));
Run Code Online (Sandbox Code Playgroud)

更有趣的是添加一个扩展方法string,使其成为可配对的:

public static KeyValuePair<string, object> PairedWith(this string key, object value)
{
    return new KeyValuePair<string, object>(key, value);
}
Run Code Online (Sandbox Code Playgroud)

用法:

MyFunction("Key1".PairedWith(5), "Key2".PairedWith(someObject));
Run Code Online (Sandbox Code Playgroud)

编辑:您还可以使用不带通用括号的字典语法,方法是Dictionary<,>:

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

public class MessageArgs : Dictionary<string, object>
{}
Run Code Online (Sandbox Code Playgroud)

用法:

MyFunction(new MessageArgs { { "Key1", 5 }, { "Key2", someObject } });
Run Code Online (Sandbox Code Playgroud)


Oli*_*bes 15

从C#7.0开始,您可以使用值元组.C#7.0不仅为元组类型和元组值引入了新类型,还简化了语法.

(string, int, double)
Run Code Online (Sandbox Code Playgroud)

也可以像这样解构一个元组

(string name, int count, double magnitude)
Run Code Online (Sandbox Code Playgroud)

这提取元组的两个独立的变量的项目Item1Item2.

现在,您可以Item2轻松调用不同数量的参数:

("test", 7, x + 5.91)
Run Code Online (Sandbox Code Playgroud)

请参阅:C#7.0中的新功能

  • 对我来说,这是最优雅的解决方案。 (2认同)

Tho*_*que 9

有趣的是,我刚刚创建(分钟前)一种允许使用匿名类型和反射的方法:

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;
}
Run Code Online (Sandbox Code Playgroud)


Luk*_*keH 7

有点破解,但你可以让你的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
    }
}
Run Code Online (Sandbox Code Playgroud)