【问题标题】:Reflecting on property to get attributes. How to do when they are defined elsewhere?反映属性以获取属性。当它们在别处定义时怎么办?
【发布时间】:2009-06-20 11:26:22
【问题描述】:

我有一个这样的类 Bar:

class Foo : IFoo {
  [Range(0,255)]
  public int? FooProp {get; set}
}

class Bar : IFoo
{
  private Foo foo = new Foo();
  public int? FooProp { get { return foo.FooProp; }
                       set { foo.FooProp= value; } } 
}

我需要找到仅反映在属性 Bar.FooProp 上的属性 [Range(0,255)]。我的意思是,当我当前正在解析时,道具是在类实例(.. new Foo())中而不是在类中装饰的。事实上 Bar.FooProp 没有属性

编辑

我在接口的定义上移动了属性,所以我要做的是解析继承的接口来找到它们。我可以这样做,因为 Bar 类必须实现 IFoo。在这种特殊情况下,我很幸运,但是当我没有接口时,问题仍然存在......我下次会注意

foreach(PropertyInfo property in properties)
{
  IList<Type> interfaces = property.ReflectedType.GetInterfaces();
  IList<CustomAttributeData> attrList;
  foreach(Type anInterface in interfaces)
  {
    IList<PropertyInfo> props = anInterface.GetProperties();
    foreach(PropertyInfo prop in props)
    {
      if(prop.Name.Equals(property.Name))
      { 
        attrList = CustomAttributeData.GetCustomAttributes(prop);
        attributes = new StringBuilder();
        foreach(CustomAttributeData attrData in attrList)
        {
            attributes.AppendFormat(ATTR_FORMAT,
                                        GetCustomAttributeFromType(prop));
        }
      }
    }
  }

【问题讨论】:

    标签: c# reflection attributes instance propertyinfo


    【解决方案1】:

    前段时间我遇到过类似的情况,我在接口中的方法上声明了一个属性,我想从实现该接口的类型的方法中获取该属性。例如:

    interface I {
      [MyAttribute]
      void Method( );
    }
    
    class C : I {
      void Method( ) { }
    }
    

    下面的代码用于检查该类型实现的所有接口,查看给定的method 实现了哪些接口成员(使用GetInterfaceMap),并返回这些成员的任何属性。在此之前,我还会检查方法本身是否存在该属性。

    IEnumerable<MyAttribute> interfaceAttributes =
      from i in method.DeclaringType.GetInterfaces( )
      let map = method.DeclaringType.GetInterfaceMap( i )
      let index = GetMethodIndex( map.TargetMethods, method )
      where index >= 0
      let interfaceMethod = map.InterfaceMethods[index]
      from attribute in interfaceMethod.GetCustomAttributes<MyAttribute>( true )
      select attribute;
    
    ...
    
    static int GetMethodIndex( MethodInfo[] targetMethods, MethodInfo method ) {
      return targetMethods.IndexOf( target =>
             target.Name == method.Name
          && target.DeclaringType == method.DeclaringType
          && target.ReturnType == method.ReturnType
          && target.GetParameters( ).SequenceEqual( method.GetParameters( ), PIC )
      );
    }
    

    【讨论】:

      【解决方案2】:

      查看FooProp 时,没有任何东西可以识别Foo 的存在(在任何时候)。或许您可以添加一个属性来识别foo 字段,并对其进行反思(通过FieldInfo.FieldType)?

      【讨论】:

      • 事实上,关键在于反映“内部”get/set 方法。我不知道是否有办法理解返回参数是对实例方法的调用..
      • 如果你在 inside 获取/设置,那么你已经知道类型...只需使用已知类型...?
      • mhh...我正在考虑将属性移动到接口定义中。所以我通过接口直接反映继承的属性,而不是实现的属性。可能是对的,马克?
      • 在接口上可以工作 - 但当方法/属性实现接口时,它会变得一点难以解决,因为显式实现、泛型等存在问题 -这不是微不足道的,但可以做到。
      • 嗨,Marc,正如刚才解释的(见编辑),接口定义比以前更丰富。它有效,但我对未来不是很满意。我的意思是,现在的主要目标是将所有分散的属性收集到一个唯一的 buddy 部分 Bar 类中。有两个原因:xVal 验证框架需要它,并且所有 UI 提示都可以驱动 codesmith 构建我的视图(文本框、编辑区域、ecc)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 2017-05-31
      • 1970-01-01
      • 2010-10-29
      • 1970-01-01
      • 2014-04-01
      • 2012-06-04
      相关资源
      最近更新 更多