[C#] Get fields of a class object dynamically

I found a nice way to get all fields of a class object dynamically.

My example is a simple class holding only parameters:
Note that I used auto-properties (shorthand for declaration and a get/set method).

public class MySimpleClass
    {
        public string StringVal1 { get; set; }
        public string StringVal2 { get; set; }
        public string StringVal3 { get; set; }
        // ... more fields
     }

My need was to override the method ToString() and to concat all the fields separated by a semicolon (;). My claims to the method were the following:

  • short and clean code
  • easily extendable

The Reflection API provides the functionallities to do this.

public override string ToString()
        {
            string retString = String.Empty;
            
            var bindingFlags = System.Reflection.BindingFlags.Instance |
                                System.Reflection.BindingFlags.NonPublic |
                                System.Reflection.BindingFlags.Public;
            List<object> listValues = this.GetType().GetFields(bindingFlags).Select(field => field.GetValue(this)).Where(value => value != null).ToList();

            foreach (var item in listValues)
            {
                // Note that you need to cast to string on objects that don't support ToSting() native! Maybe a new method to cast.
                retString += item.GetType().Name + ": " + item.ToString() + ";";
            }

            return retString;
        }

In detail:

var bindingFlags =  BindingFlags.Instance |
                                BindingFlags.NonPublic |
                                BindingFlags.Public;

This defines which fields we want to retrieve.

List<object> listValues = this.GetType().GetFields(bindingFlags).Select(field => field.GetValue(this)).Where(value => value != null).ToList();

This grabs all the field values that are not empty. If for example only the name is needed, following will do the job:

List<string> listNames = this.GetType().GetFields(bindingFlags).Select(field => field.Name).ToList();

The return type is string now!

The foreach loop concats the names with the values separated by a semicolon.

EDIT 16.06.2015:

When trying to access properties like the following, you have to use GetProperties instead of GetFields!

public int TaskId { get; set; }
public string ProjID { get; set; }

Accessing them:

string myStringValue = String.Empty;
List listProperties = this.GetType().GetProperties(bindingFlags).Where(prop => prop.GetValue(task) != null).ToList();
            foreach (var item in listProperties)
            {
                myStringValue += Environment.NewLine + item.Name + ": " + item.GetValue(this).ToString() + ";";
            }