Reputation: 1288
So, I'm supposed to design a method that I would use to log everything my app does and I was thinking of doing something like this in my methods:
Declaration:
public static void Write(string text, params object[] parameters) {}
Usage:
if (Log.On) Log.Write("Hello", valueA, valueB, valueC);
So this is elegant and clean in my view. However it has one big flaw, the values are not labeled in any way. For me, the obvious solution is a method like this:
public static void Write(string text, Dictionary<string, object> parameters) {}
but this method will clutter my code.
if (Log.On)
{
Dictionary<string, object> p = new Dictionary<string, object>();
p.Add("valueA", valueA);
p.Add("valueB", valueB);
p.Add("valueC", valueC);
Log.Write("Hello", p);
}
Any ideas how to make this method as unobtrusive as possible?
Upvotes: 3
Views: 442
Reputation: 79441
You can use this:
public static void LogValues(string text, object values)
{
var properties = values.GetType().GetProperties();
Log.WriteLine(text + ": " + string.Join(", ",
properties.Select(property =>
{
var name = property.Name;
var value = property.GetValue(values);
return name + " = " + (value != null ? value.ToString() : "null");
})));
}
Like this:
int x = 5;
double y = 7.2;
LogValues("Some message", new { y, s = "test", x });
Which will generate a line like this in your log:
Some message: y = 7.2, s = test, x = 5
The key here is in using the anonymous type for the values
parameter. This lets you pass in "named" variables, instead of just the values of those variables.
If you want a consistent ordering on the <name> = <value>
pairs printed out, you can insert a .OrderBy(property => property.Name)
before the .Select(...)
in the LINQ query.
Upvotes: 2