C# 获取重写属性的所有属性
以下面的示例代码为例:C# 获取重写属性的所有属性,c#,reflection,custom-attributes,C#,Reflection,Custom Attributes,以下面的示例代码为例: public class TestMultipleAttributesAttribute : AttributeWithPriority { public string HelpMessage { get; set; } } public class Student { [TestMultipleAttributes(HelpMessage = "Student")] publi
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;
}
想到的一个解决方案是找到
属性.DeclaringType
,然后重复这个过程,并获取它的属性。但是,我觉得这不是一个优雅的方法,我想知道是否有更好的方法。您只有一个名为TestMultipleAttributes
的属性,并且您重写了它。该属性有多个属性(Priority
和HelpMessage
)工作正常
您可以创建更多“真正”的属性,如so
StudentAttribute
和specificsudentattribute
我不知道……这是相对优雅的(尽管我确信我至少遗漏了一个特殊情况)。它应该以最接近的第一顺序枚举继承链中重写或虚拟属性上的所有自定义属性:
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 ;
}
公共静态IEnumerable AllAttribute(PropertyInfo pi)
{
如果(pi!=null)
{
//枚举此属性上的所有属性
foreach(pi.GetCustomAttributes中的对象o(false))
{
收益率(属性)o;
}
PropertyInfo parentProperty=FindNearestAncestorProperty(pi);
foreach(AllAttributesRecursive(parentProperty))中的属性attr)
{
收益率;
}
}
}
私有静态属性INFO FindNearestAncestorProperty(属性INFO属性)
{
如果(property==null)抛出新的ArgumentNullException(“property”);
如果(property.DeclaringType==null)抛出新的InvalidOperationException(“所有属性必须属于一个类型”);
//获取属性最近的“祖先”属性
const BindingFlags flags=BindingFlags.DeclaredOnly
|BindingFlags.Public | BindingFlags.NonPublic
|BindingFlags.Static | BindingFlags.Instance
;
类型t=property.DeclaringType.BaseType;
PropertyInfo祖先=null;
而(t!=null&&祖先==null)
{
祖先=t.GetProperty(property.Name,标志);
t=t.BaseType;
} ;
还祖;
}
请不要在问题标题中包含关于所用语言的信息,除非没有它就没有意义。标签就是为了这个目的。