[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() + ";";
}