Reputation: 643
OK So I'm using the code below which I found in stack overflow.
// so we can use reflection to access the object properties
public static Object GetPropValue(this Object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
// so we can use reflection to access the object properties
public static T GetPropValue<T>(this Object obj, String name)
{
Object retval = GetPropValue(obj, name);
if (retval == null) { return default(T); }
// throws InvalidCastException if types are incompatible
return (T)retval;
}
To get access to a object property using a string. So I can do stuff like this:
DateTime.Now.GetPropValue<int>("TimeOfDay.Hours")
which works well.
But my class doesn't use properties and I cannot change it as it is part of a library. I believe the it is using fields instead of properties (I didn't know they were treated differently in C# till now!). How do I access these field names and properties together? i.e for a class like this
class Student
{
public string name {get; set;} // property
public int age; // field
public Info info; // field
}
class Info
{
string a {get; set;} // property
string b; // fields
}
So I can access using this:
Student a;
a.GetPropValue<string>("info.a"); // getting a property which works!
a.GetPropValue<string>("info.b"); // getting a field value which doesn't!
As soon as I posted this I figured it out and here is my modified function
// so we can use reflection to access the object properties
public static Object GetPropertyOrFieldValue(this Object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo propertyInfo = type.GetProperty(part);
FieldInfo fieldInfo = type.GetField(part);
if (propertyInfo == null && fieldInfo == null)
{
return null;
}
obj = (propertyInfo != null) ? propertyInfo.GetValue(obj, null) : (fieldInfo != null) ? fieldInfo.GetValue(obj) : null;
}
return obj;
}
// so we can use reflection to access the object properties
public static T GetPropertyOrFieldValue<T>(this Object obj, String name)
{
Object retval = GetPropertyOrFieldValue(obj, name);
if (retval == null) { return default(T); }
// throws InvalidCastException if types are incompatible
return (T)retval;
}
Upvotes: 1
Views: 1677
Reputation: 118977
Here is the equivalent code to get a field instead of a property:
public Object GetFieldValue(this Object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null) { return null; }
Type type = obj.GetType();
FieldInfo info = type.GetField(part);
if (info == null) { return null; }
obj = info.GetValue(obj);
}
return obj;
}
// so we can use reflection to access the object properties
public T GetFieldValue<T>(this Object obj, String name)
{
Object retval = GetFieldValue(obj, name);
if (retval == null) { return default(T); }
// throws InvalidCastException if types are incompatible
return (T)retval;
}
Upvotes: 1