1

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

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

我希望我想做的事情很清楚,在此先感谢。

4

2 回答 2

1

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

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

那是你要找的吗?

于 2012-10-31T10:03:59.950 回答
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));
    }
}

这是做什么的:

  • 如果原始属性没有属性...
  • 它检查类型实现了哪些接口......
  • 并查看类属性实现了哪些接口属性...
  • 并检查是否有一个...
  • 并寻找那个属性
于 2012-10-31T10:05:30.063 回答