Reputation: 3780
I want to get a specific Attribute
on one of an object's properties.
I used this code as a starter:
public static class ObjectExtensions {
public static MemberInfo GetMember<T,R>(this T instance,
Expression<Func<T, R>> selector) {
var member = selector.Body as MemberExpression;
if (member != null) {
return member.Member;
}
return null;
}
public static T GetAttribute<T>(this MemberInfo meminfo) where T : Attribute {
return meminfo.GetCustomAttributes(typeof(T)).FirstOrDefault() as T;
}
}
Which you then call like this:
var attr = someobject.GetMember(x => x.Height).GetAttribute<FooAttribute>();
But I'd like it in one clean step like this:
var attr = someobject.GetAttribute<FooAttribute>(x => x.Height);
How do I combine those two functions to give this signature?
Update: Also, why does this not work for enums?
Upvotes: 0
Views: 159
Reputation: 8785
You won't be able to get that exact signature. For the method to work, it needs three generic type arguments (one for the object type T
, one for the attribute type TAttribute
, and one for the property type TProperty
). T
and TProperty
can be inferred from usage, but TAttribute
needs to be specified. Unfortunately, once you specify one generic type argument, you need to specify all three of them.
public static class ObjectExtensions {
public static TAttribute GetAttribute<T, TAttribute, TProperty> (this T instance,
Expression<Func<T, TProperty>> selector) where TAttribute : Attribute {
var member = selector.Body as MemberExpression;
if (member != null) {
return member.Member.GetCustomAttributes(typeof(TAttribute)).FirstOrDefault() as TAttribute;
}
return null;
}
}
This is why the two methods in the question were separate to begin with. It's easier to write
var attr = someobject.GetMember(x => x.Height).GetAttribute<FooAttribute>();
than to write
var attr = someobject.GetAttribute<Foo, FooAttribute, FooProperty>(x => x.Height);
Upvotes: 2