c# foreach (property in object)... Is there a simple way of doing this?

I have a class containing several properties (all are strings if it makes any difference).
I also have a list, which contains many different instances of the class.

While creating some unit tests for my classes I decided I wanted to loop through each object in the list and then loop through each property of that object...

I thought doing this would be as simple as...

foreach (Object obj in theList)
{
     foreach (Property theProperties in obj)
     {
         do some stufff!!;
     }
}

But this didnt work! :( I get this error...

"foreach statement cannot operate on variables of type 'Application.Object' because 'Application.Object' does not contain a public definition for 'GetEnumerator'"

Does anyone know of a way of doing this without tons of ifs and loops or without getting into anything too complex?


Give this a try:

foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
   // do stuff here
}

Also please note that Type.GetProperties() has an overload which accepts a set of binding flags so you can filter out properties on a different criteria like accessibility level, see MSDN for more details: Type.GetProperties Method (BindingFlags) Last but not least don't forget to add the "system.Reflection" assembly reference.

For instance to resolve all public properties:

foreach (var propertyInfo in obj.GetType()
                                .GetProperties(
                                        BindingFlags.Public 
                                        | BindingFlags.Instance))
{
   // do stuff here
}

Please let me know whether this works as expected.


You can loop through all non-indexed properties of an object like this:

var s = new MyObject();
foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) {
    Console.WriteLine(p.GetValue(s, null));
}

Since GetProperties() returns indexers as well as simple properties, you need an additional filter before calling GetValue to know that it is safe to pass null as the second parameter.

You may need to modify the filter further in order to weed out write-only and otherwise inaccessible properties.


Your'e almost there, you just need to get the properties from the type, rather than expect the properties to be accessible in the form of a collection or property bag:

var property in obj.GetType().GetProperties()

From there you can access like so:

property.Name
property.GetValue(obj, null)

With GetValue the second parameter will allow you to specify index values, which will work with properties returning collections - since a string is a collection of chars, you can also specify an index to return a character if needs be.


Sure, no problem:

foreach(object item in sequence)
{
    if (item == null) continue;
    foreach(PropertyInfo property in item.GetType().GetProperties())
    {
        // do something with the property
    }
}