C# 에서 상속된 객체의 Property 를 코드에 작성된 순서대로 정렬해서 보여주는 꼼수
C#처럼 강력한 Reflection 을 지원 하는 언어에서는, Attribute(Java의 Annotaion, Python의 Decorator 와 비슷함) 를 Property 에 붙여서 특수한 용도를 부여 하는 경우가 있다. 특히 노출 되는 Property를 스캔해서 UI를 만들어 주거나 하는 경우도 많은데… 다음 코드를 한번 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System.Reflection;
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class KooAttribute : Attribute
{
}
public class Foo
{
[Koo]
public string A1 { get; set; }
[Koo]
public string A2 { get; set; }
[Koo]
public string A3 { get; set; }
[Koo]
public string A4 { get; set; }
}
public class Boo : Foo
{
[Koo]
public string B1 { get; set; }
[Koo]
public string B2 { get; set; }
[Koo]
public string B3 { get; set; }
[Koo]
public string B4 { get; set; }
}
public class Program
{
public static void Main(string[] argv)
{
typeof(Boo).GetProperties()
.Where(x => x.GetCustomAttribute<KooAttribute>() != null)
.ToList()
.ForEach(x => Console.WriteLine(x.Name));
}
}
실행 결과가 예측이 되는가? 정답은 아래와 같다
1
2
3
4
5
6
7
8
B1
B2
B3
B4
A1
A2
A3
A4
Property를 스캔할 때, 일단 해당 객체의 Property 를 체크 후, 상속한 부모를 역순으로 되짚어 가며 스캔 하기 때문 인 것 같다. 하지만 보통 저런 경우, 부모가 가진 공통 속성을 먼저 보여주는것이 UI 가 자연스러운 경우가 대부분이다. 그런경우 쓸 수 있는 간단한 트릭을 소개한다.
Attibute를 아래처럼 고친다
1
2
3
4
5
6
7
8
9
10
11
12
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class KooAttribute : Attribute
{
public readonly int LineNumber;
public readonly string FilePath;
public KooAttribute([CallerLineNumber] int lineNumber = 0, [CallerFilePath] string filePath = "")
{
LineNumber = lineNumber;
FilePath = filePath;
}
}
그리고 출력부분을 아래와 같이 고친다
1
2
3
4
5
6
7
8
9
10
public static void Main(string[] argv)
{
typeof(Boo).GetProperties()
.Select(i => (property: i, attribute: i.GetCustomAttribute<KooAttribute>()))
.Where(x => x.attribute != null)
.OrderBy(x => (x.attribute.FilePath, x.attribute.LineNumber))
.Select(x => x.property)
.ToList()
.ForEach(x => Console.WriteLine(x.Name));
}
Soruce Code 의 LineNumber 를 Attribute 에 박아 넣어 그 순서대로 정렬을 하면, 기본적인 정렬이 가능하다. 만약 순서를 추가로 조정하고 싶다면 FilePath 와 LineNumber 를 임의로 조작 해 주면 큰 문제 없이 원하는 순서대로 세팅이 가능하다.
위와 같이 출력 할 경우 A1~B4 까지 코드에 적인 순서대로 나오게 된다
This post is licensed under CC BY 4.0 by the author.