我正在寻找一种方法来获得如下功能:
myFunction({"Key", value}, {"Key2", value});
我确信匿名类型的东西很容易,但我没有看到它。
我能想到的唯一解决方案是使用“params KeyValuePair [] pairs”参数,但最终会出现类似于:
myFunction(new KeyValuePair<String, object>("Key", value), new KeyValuePair<String, object>("Key2", value));
诚然,这更加丑陋。
编辑:
为了澄清,我正在写一个“消息”类来在两个不同的系统之间传递。它包含指定消息类型的ushort,以及与消息关联的“Data”的字符串到对象的字典。我希望能够在构造函数中传递所有这些信息,所以我能够做到这一点:
Agent.SendMessage(新消息(MessageTypes.SomethingHappened,“A”,x,“B”,y,“C”,z));或类似的语法。
答案 0 :(得分:59)
如果语法对于其他正常模式不好,请更改语法。怎么样:
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));
更有趣的是将扩展方法添加到string
以使其成为可配对的:
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 } });
答案 1 :(得分: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;
}
答案 2 :(得分: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
}
}
答案 3 :(得分:7)
从C#7.0开始,您可以使用值元组。 C#7.0不仅为元组类型和元组值引入了新类型,还简化了语法。
public static void MyFunction(params (string Key, object Value)[] pairs)
{
foreach (var pair in pairs) {
Console.WriteLine($"{pair.Key} = {pair.Value}");
}
}
也可以像这样解构一个元组
var (key, value) = pair;
Console.WriteLine($"{key} = {value}");
这会在两个单独的变量key
和value
中提取元组的项目。
现在,您可以轻松地使用不同数量的参数调用MyFunction
:
MyFunction(("a", 1), ("b", 2), ("c", 3));
它允许我们做像
这样的事情DrawLine((0, 0), (10, 0), (10, 10), (0, 10), (0, 0));
答案 4 :(得分:2)
使用字典:
myFunction(new Dictionary<string, object>(){
{"Key", value},
{"Key2", value}});
这是直截了当的,你只需要一个new Dictionary<K, V>
,而不是每个参数。获得钥匙和价值观是微不足道的。
或者使用匿名类型:
myFunction(new {
Key = value,
Key2 = value});
在函数内部使用不是很好,你需要反思。这看起来像这样:
foreach (PropertyInfo property in arg.GetType().GetProperties())
{
key = property.Name;
value = property.GetValue(arg, null);
}
(从我的脑海里走出来,可能是一些错误......)
答案 5 :(得分:2)
使用Dictionary ...
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"];
}
答案 6 :(得分:2)
以下是更多相同的内容:
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]);
}
}
有关初始化字典的一些详细信息,请参见here。
答案 7 :(得分:2)
使用C#4.0中的动态类型:
public class MyClass
{
// Could use another generic type if preferred
private readonly Dictionary<string, dynamic> _dictionary = new Dictionary<string, dynamic>();
public void MyFunction(params dynamic[] kvps)
{
foreach (dynamic kvp in kvps)
_dictionary.Add(kvp.Key, kvp.Value);
}
}
使用以下方式致电:
MyFunction(new {Key = "Key1", Value = "Value1"}, new {Key = "Key2", Value = "Value2"});
答案 8 :(得分:1)
你可以这样做:
TestNamedMethod(DateField => DateTime.Now, IdField => 3);
其中 DateField 和 IdField 应该是'字符串'标识符。
TestNameMethod :
public static string TestNameMethod(params Func<object, object>[] args)
{
var name = (args[0].Method.GetParameters()[0]).Name;
var val = args[0].Invoke(null);
var name2 = (args[1].Method.GetParameters()[0]).Name;
var val2 = args[1].Invoke(null);
Console.WriteLine("{0} : {1}, {2} : {3}", name, val, name2, val2);
}
性能比使用Dictionary快5%。缺点:您不能将变量用作键。
答案 9 :(得分:0)
你可以使用元组来实现与@Bryan Watts Pairing.Of
类似的东西而不需要额外的课程:
public static void MyFunction(params Tuple<string, int>[] pairs)
{
}
MyFunction(Tuple.Create("foo", 1), Tuple.Create("bar", 2));
答案 10 :(得分:0)
您还可以参考nugetpackage&#34; valuetuple&#34;,它允许您执行以下操作:
public static void MyFunction(params ValueTuple<string, object>[] pairs)
{
var pair = pairs[1];
var stringValue = pair.item1;
var objectValue = pair.item2;
}
然后你可以这样调用这个方法:
MyFunction(("string",object),("string", object));
答案 11 :(得分:0)
所以我是新手,当前无法添加注释,但这仅是通过使其通用来改进@Bryan Watts对Pairing.of
类的想法的建议,从而使其易于被其他类使用
public class Pairing
{
public static KeyValuePair<TKey, TValue> of<TKey, TValue>(TKey key, TValue value)
{
return new KeyValuePair<TKey, TValue>(key, value);
}
}