从对象获取属性

时间:2014-10-17 09:59:42

标签: c# generics reflection attributes

我希望在某个对象的属性中获得特定的Attribute

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;
  }
}

然后你会这样打电话:

var attr = someobject.GetMember(x => x.Height).GetAttribute<FooAttribute>();

但我喜欢这样一个干净的步骤:

var attr = someobject.GetAttribute<FooAttribute>(x => x.Height);

如何组合这两个函数来提供此签名?

更新:另外,为什么这对枚举不起作用?

1 个答案:

答案 0 :(得分:2)

您无法获得确切的签名。要使方法起作用,它需要三个泛型类型参数(一个用于对象类型T,一个用于属性类型TAttribute,另一个用于属性类型TProperty)。可以从使用情况推断出TTProperty,但需要指定TAttribute。不幸的是,一旦指定了一个泛型类型参数,就需要指定它们中的所有三个。

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;
    }
}   

这就是为什么问题中的两个方法是分开的原因。写起来比较容易

var attr = someobject.GetMember(x => x.Height).GetAttribute<FooAttribute>();

而不是写

var attr = someobject.GetAttribute<Foo, FooAttribute, FooProperty>(x => x.Height);