简体   繁体   中英

Concise Dynamic List of Key Value Pairs

I'm writing a C# app. In that app, I have a need to pass an arbitrary list of key value pairs. I want to pass those key/values to a utility method that looks something like this:

public void PrettyPrint(string message, [type?] kvp)
{
  Console.WriteLine(message);
  foreach (var p in kvp)
  {
    Console.Write(p.Key + "\t\t\t" + p.Value);
  }
}

Please note, that's just pseduocode. I then want to call this function using something like this:

PrettyPrint("Results:", { quantity:4, total:"$1.23", tax:"0.10" });

Everything I see using C# seems bulky for just passing key value pairs. Am I overrlooking something? Is there a concise way of just passing a dynamic list of key value pairs in C#

You could just use C# 7's value tuples and the params keyword:

public static void PrettyPrint(string message, params (object key, object value)[] kvp)
{
    Console.WriteLine(message);
    foreach (var p in kvp)
    {
        Console.Write(p.key + "\t\t\t" + p.value);
    }
}

Called like this:

PrettyPrint("Results: ", ("quantity", 4), ("total", "$1.23"), ("tax", 0.10));

Or, storing the pairs in a variable:

(object, object)[] pairs = {("quantity", 4), ("total", "$1.23"), ("tax", 0.10)};
PrettyPrint("Results: ", pairs);

or slightly more concisely using the loop like foreach (var (key, value) in kvp) to avoid the p and the item names in the method signature

public static void PrettyPrint(string message, params (object, object)[] kvp)
{
    Console.WriteLine(message);
    foreach (var (key, value) in kvp)
    {
        Console.Write($"{key}\t\t\t{value}");
    }
}

The closest (by syntax) to what you need I think can be achieved by accepting plain object and reflect over its properties:

public static void PrettyPrint(string message, object kvp) {
    if (kvp == null)
        return;
    Console.WriteLine(message);
    foreach (var p in kvp.GetType().GetProperties()) {
        Console.Write(p.Name + "\t\t\t" + p.GetValue(kvp));
    }
}

That is because then you can pass anonymous objects there:

PrettyPrint("Results:", new { quantity = 4, total = "$1.23", tax = "0.10" });

That's basically the same as you would do that in javascipt (which syntax you used for an example of what you want).

You could use a Dictionary ( https://msdn.microsoft.com/de-de/library/xfhwa508(v=vs.110).aspx ) or a List<Tuple<string,float>> for example

PrettyPrint("Results:", new Dictionary<string, float>() 
{
   { "quantity",4 }, 
   { "total", 1.23 }
});

You can use, for example, Json.Net. This way you can submit absolutely any object.

public void PrettyPrint(string message, object kvp)
{
    Console.WriteLine(message);
    var json = JsonConvert.SerializeObject(kvp, Formatting.Indented);
    Console.WriteLine(json);
}

The result is quite pretty.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM