The only way I know it's by reflection with a code like this:
Reflection is one way, it's also expensive (so I've heard), so you create a cache to speed up multiple property looks ups (this is what asp.net-mvc does). Something like (totally example code):
private static Dictionary<PropertyInfoKey, PropertyInfo> propertyCache =
new Dictionary<PropertyInfoKey, PropertyInfo>()
private class PropertyInfoKey : IEquatable
{
public PropertyInfoKey(string fullName, string propertyName)
{
FullName = fullName;
PropertyName = propertyName
}
public string FullName { get; private set; }
public string PropertyName { get; private set; }
public bool Equals(PropertyInfoKey other)
{
if ( ..// do argument checking
var result = FullName == other.FullName
&& PropertyName == other.PropertyName;
return result;
}
}
public static bool TryGetPropValue<T>(T src,
string propName,
out object value)
where T : class
{
var key = new PropertyInfoKey(
fullName: typeof(T).FullName,
propertyName: propName
);
PropertyInfo propertyInfo;
value = null;
var result = propertyCache.TryGetValue(key, out propertyInfo);
if (!result)
{
propertyInfo = typeof(T).GetProperty(propName);
result = (propertyInfo != null);
if (result)
{
propertyCache.Add(key, propertyInfo)
}
}
if (result)
{
value = propertyInfo.GetValue(src, null);
}
return result;
}
(*maybe you could use a HashSet
instead since PropertyInfoKey could technically hold the PropertyInfo
as well, and it's implementing IEquatable
)
OR....
If you are doing this because you have a lot of classes that share similar properties but are completely different and unrelated...
public interface IName
{
public string Name { get; }
}
public class Car : IName
{
public string Name { get; set; }
public string Manufacturer { get; set; }
}
public class Animal : IName
{
public string Name { get; set; }
public string Species { get; set; }
}
public class Planet : IName
{
public string Name { get; set; }
public string ContainSystem { get; set; }
}
Then you can
public static string GetName(this IName instance)
{
return instance.Name;
}