programing

지정된 속성을 가진 속성 목록을 가져오는 방법은 무엇입니까?

mailnote 2023. 5. 11. 21:43
반응형

지정된 속성을 가진 속성 목록을 가져오는 방법은 무엇입니까?

저는 타입이 있어요.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]().

제가 가장 많이 사용하게 된 해결책은 토마스 페트리섹의 대답에 기반을 두고 있습니다.저는 보통 속성과 속성 모두를 가지고 무언가를 하고 싶습니다.

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)에는 본격적인 Reflection이 있습니다.식 트리를 사용하여 ID에 대한 세부 구문을 갖는 도우미 클래스입니다.속성 정보.사용률은 다음과 같습니다.

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

나는 수업을 위한 확장 방법을 만들었습니다.Type.

저는 C# 7.0에 소개된 LINQ와 Tuples를 사용했습니다.

    public static class TypeExtensionMethods
    {
        public static List<(PropertyInfo Info, T Attribute)> GetPropertyWithAttribute<T>(this Type type) where T : Attribute
        {
#pragma warning disable CS8619 // Checked here: .Where(x => x.Value != default)

            return type.GetProperties()
                       .Select(x => (Info: x, Attribute: GetAttribute<T>(x)))
                       .Where(x => x.Attribute != default)
                       .ToList();

#pragma warning restore CS8619 // Checked here: .Where(x => x.Value != default) 
        }

        private static T? GetAttribute<T>(PropertyInfo info) where T : Attribute
        {
            return (T?)info.GetCustomAttributes(typeof(T), true)
                           .FirstOrDefault();
        }
    }

다음과 같이 사용할 수 있습니다.

var props = typeof(DemoClass).GetPropertyWithAttribute<MyAttribute>();

foreach((PropertyInfo Info, MyAttribute Attribute) in props)
{
    Console.WriteLine($"Property {Info.Name}: {Attribute.DisplayName}");
}

프라그마를 제거할 수는 있지만 경고는 필요 없습니다

언급URL : https://stackoverflow.com/questions/2281972/how-to-get-a-list-of-properties-with-a-given-attribute

반응형