/// <summary>
/// walks the property path and gets the value of the property on the object 'value'
/// example: path = "Company.Address[1].City"
/// </summary>
/// <param name="value">object to parse the property value from</param>
/// <param name="path">path to the property</param>
public static object FollowPropertyPath(object value, string path)
{
if (value == null) throw new ArgumentNullException("value");
if (path == null) throw new ArgumentNullException("path");
Type currentType = value.GetType();
object obj = value;
foreach (string propertyName in path.Split('.')) // split property path by "."
{
if (currentType != null)
{
PropertyInfo property = null;
int brackStart = propertyName.IndexOf("["); // parsing out if the property is an indexer property
int brackEnd = propertyName.IndexOf("]");
property = currentType.GetProperty(brackStart > 0 ? propertyName.Substring(0, brackStart) : propertyName);
obj = property.GetValue(obj, null);
if (brackStart > 0) // just for indexer properties
{
string index = propertyName.Substring(brackStart + 1, brackEnd - brackStart - 1); // get the index
// determine type of indexer property. extend the following if other types are required
foreach (Type iType in obj.GetType().GetInterfaces())
{
// http://stackoverflow.com/questions/852233/getting-values-of-a-generic-idictionary-using-reflection
if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
{
obj = typeof(ReflectorUtil).GetMethod("GetDictionaryElement")
.MakeGenericMethod(iType.GetGenericArguments())
.Invoke(null, new object[] { obj, index });
break;
}
if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IList<>))
{
obj = typeof(ReflectorUtil).GetMethod("GetListElement")
.MakeGenericMethod(iType.GetGenericArguments())
.Invoke(null, new object[] { obj, index });
break;
}
}
}
// allow for derived properties in the path (property.PropertyType will get the defined type, obj.GetType the actual one)
currentType = obj != null ? obj.GetType() : null; //property.PropertyType;
}
else return null;
}
return obj;
}
public static TValue GetDictionaryElement<TKey, TValue>(IDictionary<TKey, TValue> dict, object index)
{
TKey key = (TKey)Convert.ChangeType(index, typeof(TKey), null);
return dict[key];
}
public static T GetListElement<T>(IList<T> list, object index)
{
return list[Convert.ToInt32(index)];
}
Posts mit dem Label reflection werden angezeigt. Alle Posts anzeigen
Posts mit dem Label reflection werden angezeigt. Alle Posts anzeigen
Donnerstag, 17. März 2011
Get the property value by its path
Labels:
C# 3.5,
dictionary,
generic,
list,
path,
property,
reflection,
value
Abonnieren
Posts (Atom)
