[c#] 주어진 속성을 가진 속성 목록을 얻는 방법?

유형 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


답변