获取属性来自已实现接口的属性的属性

时间:2012-10-31 09:52:31

标签: c# generics inheritance attributes

如果我在界面中有很多属性,但在示例中我将只使用一个,因为它演示了我想要实现的目标。

  interface IFoo
  {
    [Bar()]
    string A { get; set; }
  }
 class Base { }
 class Foo : Base, IFoo
 {
   public string A { get; set; }
 }

所以当我这样做时:

Foo f = new Foo();
f.A = "Value";
Attribute b = Attribute.GetCustomAttribute(f.GetType().GetProperty("A"), typeof(Bar));

我希望能够获取Bar属性的实例。大多数这是在泛型类中完成的,我使用我的属性作为验证模型,所以我不能隐式地转换为接口然后在接口中获取属性的属性,因为我永远不知道接口将是什么类型或者将实现它的类型。我需要一些方法从我的Base实例中获取该属性。

public void GenericMethod<T>(T instance) where T : Base
{
    //Get my instance of Bar here.
}

我希望我提前做的事情是清楚的,先谢谢。

2 个答案:

答案 0 :(得分:1)

这将为您提供应用于Bar类型的所有属性的所有自定义属性instance的列表:

var attibutes = instance.GetType().GetInterfaces()
                    .SelectMany(i => i.GetProperties())
                    .SelectMany(
                        propertyInfo =>
                        propertyInfo.GetCustomAttributes(typeof (BarAttribute), false)
                    );

这就是你要找的东西吗?

答案 1 :(得分:0)

属性Foo.A 没有任何属性。只有IFoo.A具有该属性。你需要使用:

Attribute b = Attribute.GetCustomAttribute(typeof(IFoo).GetProperty("A"), ...);

您可以做的唯一其他事情是通过f.GetType().GetInterfaceMap(typeof(IFoo))显式检查接口表,也可以检查f.GetType().GetInterfaces()中具有“A”的每个接口。

类似的东西(这很麻烦):

var outerProp = f.GetType().GetProperty("A");
Attribute b = Attribute.GetCustomAttribute(outerProp, typeof(BarAttribute));
if (b == null)
{
    var candidates = (from iType in f.GetType().GetInterfaces()
                      let prop = iType.GetProperty("A")
                      where prop != null
                      let map = f.GetType().GetInterfaceMap(iType)
                      let index = Array.IndexOf(map.TargetMethods, outerProp.GetGetMethod())
                      where index >= 0 && map.InterfaceMethods[index] == prop.GetGetMethod()
                      select prop).Distinct().ToArray();
    if (candidates.Length == 1)
    {
        b = Attribute.GetCustomAttribute(candidates[0], typeof(BarAttribute));
    }
}

这是做什么的:

  • 如果原始属性没有属性...
  • 它检查类型实现的接口...
  • 并查看class-property实现的接口属性...
  • 并检查是否只有一个......
  • 并查找该
  • 上的属性