지정된 속성을 가진 속성 목록을 가져오는 방법은 무엇입니까?
저는 타입이 있어요.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
'programing' 카테고리의 다른 글
| HTML.ActionLink 메서드 (0) | 2023.05.11 |
|---|---|
| 디렉토리의 모든 파일에 대해 명령 실행 (0) | 2023.05.11 |
| xml을 사용하여 문자열 배열 리소스의 문자열 참조 (0) | 2023.05.11 |
| VB의 메서드 본문 내에서는 코드 영역을 사용할 수 없습니다.NET? (0) | 2023.05.11 |
| csv.오류: 반복기는 바이트가 아닌 문자열을 반환해야 합니다. (0) | 2023.05.11 |