Reputation: 533
I have the following method which I use to iterate through all properties (just properties) in my classes and print on screen their names and values they hold, if any.
public static void PrintProperties(object obj, int indent = 1)
{
if ( obj == null )
return;
string indentString = new string (' ', indent);
Type objType = obj.GetType ();
PropertyInfo[] properties = objType.GetProperties ();
foreach ( PropertyInfo property in properties )
{
object propValue = property.GetValue (obj, null);
var elems = propValue as IList;
if ( elems != null )
{
foreach ( var item in elems )
{
PrintProperties (item, indent + 3);
}
}
else
{
if ( property.PropertyType.Assembly == objType.Assembly )
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
PrintProperties (propValue, indent + 2);
}
else
{
Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
}
}
}
Unfortunately, I change a property in one of my Classes from string to List<string>
to accommodate for multiple values that I had to assign there, and now I get error
System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'
which I don't know how to fix, and most probably is because I have a property that is List.
How can i fix so that when I encounter such a property, to list all its values?
Could someone help me please?
Upvotes: 0
Views: 888
Reputation: 136239
The problem in this line where the error occurs:
object propValue = property.GetValue (obj, null);
Has nothing to do with the list per se. It is the recursive nature of your method trying to do enumerate all the properties on string
. A simple solution, if you only want to print the values of the list is to change the part that enumerates the list as simply:
var elems = propValue as IList;
if ( elems != null )
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
foreach ( var item in elems )
{
Console.WriteLine("{0}{1}",new string (' ', indent+2),item);
}
}
https://dotnetfiddle.net/NBOA4u
Upvotes: 1
Reputation: 109862
You have to do three things to fix your implementation:
int
then it won't get printed out.Something along these lines should work:
public static void PrintProperties(object obj, int indent = 1)
{
if (obj == null)
return;
string indentString = new string(' ', indent);
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue;
if (objType == typeof(string))
return; // Handled at a higher level, so nothing to do here.
if (property.PropertyType.IsArray)
propValue = (Array)property.GetValue(obj);
else
propValue = property.GetValue(obj, null);
var elems = propValue as IList;
if (elems != null)
{
Console.WriteLine("{0}{1}: IList of {2}", indentString, property.Name, propValue.GetType().Name);
for (int i = 0; i < elems.Count; ++i)
{
Console.WriteLine("{0}{1}[{2}] == {3}", indentString, property.Name, i, elems[i]);
if (objType != typeof(string))
PrintProperties(elems[i], indent + 3);
}
}
else
{
if (property.PropertyType.Assembly == objType.Assembly)
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
PrintProperties(propValue, indent + 2);
}
else
{
Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
}
}
}
}
You will probably want to adjust the output to suit what you actually want, but this should give you the gist.
Upvotes: 1