C# 参数中的键值对
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1319708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Key value pairs in C# Params
提问by Quantumplation
I'm looking for a way to have a function such as:
我正在寻找一种具有以下功能的方法:
myFunction({"Key", value}, {"Key2", value});
I'm sure there's something with anonymous types that would be pretty easy, but I'm not seeing it.
我确信有些匿名类型的东西会很容易,但我没有看到。
The only solution I can think of is to have a params KeyValuePair<String, object>[] pairs
parameter, but that ends up being something similar to:
我能想到的唯一解决方案是有一个params KeyValuePair<String, object>[] pairs
参数,但最终类似于:
myFunction(new KeyValuePair<String, object>("Key", value),
new KeyValuePair<String, object>("Key2", value));
Which is, admittedly, much uglier.
不可否认,这要丑得多。
EDIT:
编辑:
To clarify, I'm writing a Message
class to pass between 2 different systems. It contains a ushort
specifying the the Message Type, and a dictionary of string to object for "Data" associated with the message. I'd like to be able to pass all this information in the constructor, so I am able to do this:
澄清一下,我正在编写一个Message
类来在 2 个不同的系统之间传递。它包含ushort
指定消息类型的字符串,以及与消息关联的“数据”对象的字符串字典。我希望能够在构造函数中传递所有这些信息,所以我可以这样做:
Agent.SendMessage(new Message(MessageTypes.SomethingHappened, "A", x, "B", y, "C", z));
or similar syntax.
或类似的语法。
采纳答案by Bryan Watts
When the syntax is bad for an otherwise decent pattern, change the syntax. How about:
当语法对其他体面的模式不利时,请更改语法。怎么样:
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);
}
}
Usage:
用法:
MyFunction(Pairing.Of("Key1", 5), Pairing.Of("Key2", someObject));
Even more interesting would be to add an extension method to string
to make it pairable:
更有趣的是添加一个扩展方法string
以使其可配对:
public static KeyValuePair<string, object> PairedWith(this string key, object value)
{
return new KeyValuePair<string, object>(key, value);
}
Usage:
用法:
MyFunction("Key1".PairedWith(5), "Key2".PairedWith(someObject));
Edit: You can also use the dictionary syntax without the generic brackets by deriving from Dictionary<,>
:
编辑:您还可以通过派生使用没有通用括号的字典语法Dictionary<,>
:
public void MyFunction(MessageArgs args)
{
// ...
}
public class MessageArgs : Dictionary<string, object>
{}
Usage:
用法:
MyFunction(new MessageArgs { { "Key1", 5 }, { "Key2", someObject } });
回答by Stefan Steinegger
Using a dictionary:
使用字典:
myFunction(new Dictionary<string, object>(){
{"Key", value},
{"Key2", value}});
Which is straight forward, you need only one new Dictionary<K, V>
, not for each argument. It's trivial to get the keys and values.
这是直接的,您只需要一个new Dictionary<K, V>
,而不是每个参数。获取键和值很简单。
Or with an anonymous type:
或者使用匿名类型:
myFunction(new {
Key = value,
Key2 = value});
Which is not very nice to use inside the function, you'll need reflection. This would look something like this:
在函数内部使用不是很好,您需要反射。这看起来像这样:
foreach (PropertyInfo property in arg.GetType().GetProperties())
{
key = property.Name;
value = property.GetValue(arg, null);
}
(Staight from my head, probably some errors...)
(直接从我的脑海中,可能有些错误......)
回答by JP Alioto
Use a 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"];
}
回答by Chris S
Here's more of the same:
以下是更多相同的内容:
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]);
}
}
Some details on initialising a dictionary can be found here.
可以在此处找到有关初始化字典的一些详细信息。
回答by LukeH
A bit of a hack, but you could have your Message
class implement the IEnumerable
interface and give it an Add
method. You'll then be able to use collection initializer syntax:
有点黑客,但你可以让你的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
}
}
回答by Thomas Levesque
Funny, I just created (minutes ago) a method that allows to do that, using anonymous types and reflection :
有趣的是,我刚刚(几分钟前)创建了一个允许这样做的方法,使用匿名类型和反射:
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;
}
回答by yeroo
You can do that:
你可以这样做:
TestNamedMethod(DateField => DateTime.Now, IdField => 3);
where DateFieldand IdFieldare supposed to be a 'string' identifiers.
其中DateField和IdField应该是“字符串”标识符。
The TestNameMethod:
该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);
}
Performance is 5% faster than using Dictionary. Disadvantage: you can't use variable as a key.
性能比使用 Dictionary 快 5%。缺点:不能使用变量作为键。
回答by djoyce
With dynamic type in C# 4.0:
在 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);
}
}
Call using:
调用使用:
MyFunction(new {Key = "Key1", Value = "Value1"}, new {Key = "Key2", Value = "Value2"});
回答by Pakman
You could use Tuples to achieve something similar to @Bryan Watts's Pairing.Of
without the extra class:
您可以使用元组来实现类似于@Bryan Watts 的东西,Pairing.Of
而无需额外的类:
public static void MyFunction(params Tuple<string, int>[] pairs)
{
}
MyFunction(Tuple.Create("foo", 1), Tuple.Create("bar", 2));
回答by Rob. E
You could also reference the nugetpackage "valuetuple", which allows you to do the following:
您还可以引用 nugetpackage“valuetuple”,它允许您执行以下操作:
public static void MyFunction(params ValueTuple<string, object>[] pairs)
{
var pair = pairs[1];
var stringValue = pair.item1;
var objectValue = pair.item2;
}
You can then call the method like this:
然后,您可以像这样调用该方法:
MyFunction(("string",object),("string", object));