유형 t
이 있으며 속성이있는 공용 속성 목록을 가져오고 싶습니다 MyAttribute
. 속성은 다음과 AllowMultiple = false
같이 로 표시됩니다 .
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
현재 내가 가진 것은 이것이지만 더 나은 방법이 있다고 생각합니다.
foreach (PropertyInfo prop in t.GetProperties())
{
object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
if (attributes.Length == 1)
{
//Property with my custom attribute
}
}
이것을 어떻게 향상시킬 수 있습니까? 이것이 중복이라면 사과드립니다. 거대한 반사 스레드가 있습니다 … 매우 인기있는 주제 인 것처럼 보입니다.
답변
var props = t.GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(MyAttribute)));
이것은 속성 인스턴스를 구체화 할 필요가 없습니다 (즉,보다 저렴합니다 GetCustomAttribute[s]()
.
답변
내가 가장 많이 사용하는 솔루션은 Tomas Petricek의 답변을 기반으로합니다. 나는 보통 뭔가하고 싶은 모두 속성과 재산을.
var props = from p in this.GetType().GetProperties()
let attr = p.GetCustomAttributes(typeof(MyAttribute), true)
where attr.Length == 1
select new { Property = p, Attribute = attr.First() as MyAttribute};
답변
내가 아는 한, 리플렉션 라이브러리를 더 똑똑하게 작업하는 데 더 좋은 방법은 없습니다. 그러나 LINQ를 사용하여 코드를 조금 더 멋지게 만들 수 있습니다.
var props = from p in t.GetProperties()
let attrs = p.GetCustomAttributes(typeof(MyAttribute), true)
where attrs.Length != 0 select p;
// Do something with the properties in 'props'
이것이 코드를 더 읽기 쉬운 방식으로 구성하는 데 도움이된다고 생각합니다.
답변
항상 LINQ가 있습니다 :
t.GetProperties().Where(
p=>p.GetCustomAttributes(typeof(MyAttribute), true).Length != 0)
답변
리플렉션의 속성을 정기적으로 다루는 경우 일부 확장 방법을 정의하는 것이 매우 실용적입니다. 많은 프로젝트에서 볼 수 있습니다. 여기에 제가 가진 것이 있습니다 :
public static bool HasAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute
{
var atts = provider.GetCustomAttributes(typeof(T), true);
return atts.Length > 0;
}
당신이 사용할 수있는 typeof(Foo).HasAttribute<BarAttribute>();
다른 프로젝트 (예 : StructureMap)에는 Expression Tree를 사용하여 PropertyInfo와 같은 신원에 대한 훌륭한 구문을 갖는 본격적인 ReflectionHelper 클래스가 있습니다. 그런 다음 사용법은 다음과 같습니다.
ReflectionHelper.GetProperty<Foo>(x => x.MyProperty).HasAttribute<BarAttribute>()
답변
이전 답변 외에도 Any()
컬렉션 길이를 확인 하는 대신 방법을 사용하는 것이 좋습니다.
propertiesWithMyAttribute = type.GetProperties()
.Where(x => x.GetCustomAttributes(typeof(MyAttribute), true).Any());
dotnetfiddle의 예 : https://dotnetfiddle.net/96mKep