Reputation: 143
I am working on adding some logging to my program to help with tracking function calls and parameters. To do this I have created a function that takes a parameter array of objects and then at runtime I determine the type to define how each object should be handled. The issue I'm running into is if I have a List of SqlParameter in parameters[1], how do I generically handle this so I don't need to define every type of List I can potentially pass in? For each item in the List I am just going to call ToString so I don't have any need to know the actual type. I've tried below to convert it to a list of object but that is failing.
public static string LogParameters(params object[] parameters)
{
string returnValue = "\n";
if (parameters != null)
{
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i] == null)
{
returnValue += $"---->null null\n";
}
else if (parameters[i].GetType().IsGenericType)
{
// error is happening on this line
List<object> objects = (List<object>)parameters[i];
returnValue += GetLogParameterTypeText(objects);
for (int x = 0; x < objects.Count; x++)
{
returnValue += GetLogParameterTypeText(objects[x], "----");
}
}
else if (parameters[i].GetType().IsArray)
{
object[] objects = (object[])parameters[i];
returnValue += GetLogParameterTypeText(objects);
for (int x = 0; x < objects.Length; x++)
{
returnValue += GetLogParameterTypeText(objects[x], "----");
}
}
else
{
returnValue += GetLogParameterTypeText(parameters[i]);
}
}
}
return returnValue;
}
Here is a sample of how the function is called
Log.Information($"{LogParameters(fieldName, dataType, fieldValue, panelName)}");
Upvotes: 1
Views: 454
Reputation: 63722
Don't use List<T>
, use IEnumerable<T>
. Unlike a list, enumerables allow for type variance, so List<string>
does actually implement IEnumerable<object>
, while it does not implement either List<object>
or IList<object>
.
For bonus points, arrays also implement IEnumerable
, so you can change your logic to something like
if (parameters[i] is IEnumerable<object> enumerable)
{
returnValue += GetLogParameterTypeText(enumerable);
foreach (var object in enumerable)
{
returnValue += GetLogParameterTypeText(object, "----");
}
}
You might also want to consider using StringBuilder
to build the return value; concatenating strings requires a lot more allocations.
Upvotes: 3