I use a method similar to the following to get some precomputed metadata related to a Type's properties.
MyData GetProperty<T, U>(Expression<Func<T, U>> member)
{
// Get the property referenced in the lambda expression
MemberExpression expression = member.Body as MemberExpression;
PropertyInfo property = expression.Member as PropertyInfo;
// get the properties in the type T
PropertyInfo[] candidates = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
// Find the match
foreach (PropertyInfo candidate in candidates)
if (candidate == property)
return GetMetaData<T>(candidate);
throw new Exception("Property not found.");
}
// Returns precomputed metadata
MyData GetMetaData<T>(PropertyInfo property) { ... }
As you would expect, it works when used as follows:
var data = PropertyInfo((Employee e) => e.Name);
But not when used in the following generic method:
void MyGenericMethod<T>(int id) where T : IEmployee
{
var data = PropertyInfo((T e) => e.Name);
}
It fails because the declaring type of property
in the first method is now IEmployee
, so the property in the lambda doesn't match the property in the type. How can I get them to match, without relying on the names of the properties? (There can be multiple properties with the same name if interfaces are implemented explicitly, so p1.Name == p2.Name
won't cut it).