【问题标题】:get all attributes of an overriden property获取覆盖属性的所有属性
【发布时间】:2014-02-27 18:49:09
【问题描述】:

以下面的示例代码为例:

    public class TestMultipleAttributesAttribute : AttributeWithPriority
    {
        public string HelpMessage { get; set; }
    }

    public class Student


    {
        [TestMultipleAttributes(HelpMessage = "Student")]
        public virtual string Name { get; set; }

    }

    public class SpecificStudent : Student
    {
        [TestMultipleAttributes(Priority = 100, HelpMessage = "SpecificStudent")]
        public override string Name { get; set; }
    }

有什么方法可以通过反射获得TestMultipleAttributes 的两个实例以获取相同的覆盖属性?

我尝试了以下代码:

   [Test]
    public void testMultipleAttribs()
    {
        var property = typeof(SpecificStudent).GetProperties().FirstOrDefault(x => x.Name == "Name");

        var attribList = property.Attributes; //returns none
        var customAttribs = property.CustomAttributes.ToList(); //returns 1
        var customAttribs2 = property.GetCustomAttributes(inherit: true);// returns 1
        int k = 5;

    }

想到的一个解决方案是找到property.DeclaringType,并重复该过程,并获取它的属性。但是,我不认为这是一种优雅的方法,我想知道是否有更好的方法。

【问题讨论】:

  • 请不要在问题标题中包含有关所用语言的信息,除非没有它就没有意义。标记用于此目的。

标签: c# reflection custom-attributes


【解决方案1】:

您只有一个名为 TestMultipleAttributes 的属性并且您覆盖了它。该属性有多个属性(PriorityHelpMessage)它可以正常工作。

您可以创建更多“真正”的属性,例如 StudentAttributeSpecificStudentAttribute

【讨论】:

    【解决方案2】:

    我不知道...这是相对优雅的(尽管我确信我至少遗漏了一种特殊情况)。它应该以最近的优先顺序枚举继承链中被覆盖或虚拟属性上的所有自定义属性:

    public static IEnumerable<Attribute>  AllAttributes( PropertyInfo pi )
    {
      if ( pi != null )
      {
        // enumerate all the attributes on this property
        foreach ( object o in pi.GetCustomAttributes( false ) )
        {
          yield return (Attribute) o ;
        }
    
        PropertyInfo parentProperty = FindNearestAncestorProperty(pi) ;
        foreach( Attribute attr in AllAttributesRecursive(parentProperty) )
        {
          yield return attr ;
        }
    
      }
    
    }
    
    private static PropertyInfo FindNearestAncestorProperty( PropertyInfo property )
    {
      if ( property == null ) throw new ArgumentNullException("property") ;
      if ( property.DeclaringType == null ) throw new InvalidOperationException("all properties must belong to a type");
    
      // get the property's nearest "ancestor" property
      const BindingFlags flags = BindingFlags.DeclaredOnly
                               | BindingFlags.Public | BindingFlags.NonPublic
                               | BindingFlags.Static | BindingFlags.Instance
                               ;
      Type         t        = property.DeclaringType.BaseType ;
      PropertyInfo ancestor = null ;
    
      while ( t != null && ancestor == null )
      {
        ancestor = t.GetProperty(property.Name,flags) ;
        t        = t.BaseType ;
      } ;
    
      return ancestor ;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-01-17
      • 2011-11-06
      • 1970-01-01
      • 2020-07-17
      • 2012-03-10
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多