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
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.
With dynamic type in 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"});
Since C# 7.0, you can use value tuples. C# 7.0 not only introduces a new type but a simplified syntax for tuple types and for tuple values. A tuple type is simply written as a list of types surrounded by braces:
(string, int, double)
The corresponding elements are named Item1
, Item2
, Item2
. You can also specify optional aliases. These aliases are only syntactic sugar (a trick of the C# compiler); the tuples are still based on the invariant (but generic) System.ValueTuple<T1, T2, ...> struct.
(string name, int count, double magnitude)
Tuple values have a similar syntax, except that you specify expressions instead of types
("test", 7, x + 5.91)
or with the aliases
(name: "test", count: 7, magnitude: x + 5.91)
Example with params
array:
public static void MyFunction(params (string Key, object Value)[] pairs)
{
foreach (var pair in pairs) {
Console.WriteLine($"{pair.Key} = {pair.Value}");
}
}
It is also possible to deconstruct a tuple like this
var (key, value) = pair;
Console.WriteLine($"{key} = {value}");
This extracts the items of the tuple in two separate variables key
and value
.
Now, you can call MyFunction
with a varying number of arguments easily:
MyFunction(("a", 1), ("b", 2), ("c", 3));
It allows us to do things like
DrawLine((0, 0), (10, 0), (10, 10), (0, 10), (0, 0));
See: New Features in C# 7.0
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"];
}
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:
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
}
}
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:
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<,>
:
public void MyFunction(MessageArgs args)
{
// ...
}
public class MessageArgs : Dictionary<string, object>
{}
Usage:
MyFunction(new MessageArgs { { "Key1", 5 }, { "Key2", someObject } });