본문 바로가기
NOTE/Programming

[C#] Reflection && Attributes

by DevAthena 2018. 4. 1.

참고 : http://blog.eairship.kr/152 ( 누구나가 다 이해할 수 있는 프로그래밍 첫걸음 블로그 )

를 공부하면서 나중에 다시보기 쉽게 정리한 것입니다. 원본은 위 글입니다.!


리플렉션(Reflection)

- 프로그램 실행 도중에 객체의 정보를 조사하거나

- 다른 모듈에 선언된 인스턴스를 생성하거나

- 기존 개체에서 형식을 가져오고 해당하는 메소드를 호출하거나

- 해당 필드와 속성에 접근 할 수 있는 기능을 제공하거나


GetType() -> Type

GetMembers() -> MemberInfo[]

GetMethods() -> MethodInfo[]

GetFields() -> FieldInfo[]


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
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading.Tasks;
 
namespace ConsoleApplication43
{
    class Animal
    {
        public int age;
        public string name;
 
        public Animal(string name, int age)
        {
            this.age = age;
            this.name = name;
        }
        public void eat()
        {
            Console.WriteLine("먹는다!");
        }
        public void sleep()
        {
            Console.WriteLine("잔다!");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Animal animal = new Animal("고양이"4);
            Type type = animal.GetType();
 
            ConstructorInfo[] coninfo = type.GetConstructors();
            Console.Write("생성자(Constructor) : ");
            foreach (ConstructorInfo tmp in coninfo)
                Console.WriteLine("\t{0}", tmp);
            Console.WriteLine();
 
            MemberInfo[] meminfo = type.GetMethods();
            Console.Write("메소드(Method) : ");
            foreach (MethodInfo tmp in meminfo)
                Console.Write("\t{0}", tmp);
            Console.WriteLine();
 
            FieldInfo[] fieldinfo = type.GetFields();
            Console.Write("필드(Field) : ");
            foreach (FieldInfo tmp in fieldinfo)
                Console.Write("\t{0}", tmp);
            Console.WriteLine();
        }
    }
}
cs



결과 : 생성자(Constructor) :   Void.ctor(System.String, Int32)


메소드(Method) :   Void eat()    Void sleep()    System.String ToString()

Boolean Equals(System.Object)    Int32 GetHashCode()    System.Type GetType()


필드(Field) :    Int32 age    System.String name




애트리뷰트(Attrtibute)

- 클래스에 메타데이터를 추가 할 수 있도록 제공

- 클래스부터 시작해서 메소드, 구조체, 생성자, 프로퍼티, 필드, 이벤트, 인터페이스 등에 사용가능.

- 커스텀 애트리뷰트

- 내장되어있는 공통 애트리뷰트 : Obsolete, Conditional, DllImport ... 

- 기본 형식

1
[attribute명(positional_parameter, name_parameter = value, ...)]
cs



* Conditional : 해당 기호가 정의되어 잇으면 호출이 포함되고, 그렇지 않다면 호출이 생략

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
#define TEST
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Reflection;
using System.Threading.Tasks;
 
namespace ConsoleApplication43
{
    class Program
    {
        // TEST가 정의되어 있어야만 호출이 가능합니다.
        [Conditional("TEST")]
        public void TestConditional()
        {
            Console.WriteLine("TestConditional!");
        }
 
        static void Main(string[] args)
        {
            Program program = new Program();
 
            program.TestConditional();
        }
    }
}
cs


결과 : TestConditional!



* Obsolete : 클래스 내에서 더이상 사용되지 않는 함수를 사용하려고 할 때 이 요소를 쓰지 말것을 권고하는 경고 혹은 에러를 발생.

(두번째 인자 값이 true이면 에러가 발생)

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Reflection;
using System.Threading.Tasks;
 
namespace ConsoleApplication43
{
    class Program
    {
        [Obsolete("OldMethod()는 더이상 사용하지 않으므로, NewMethod()를 사용해주세요.")]
        public void OldMethod() { Console.WriteLine("OLD!"); }
 
        public void NewMethod() { Console.WriteLine("NEW!"); }
 
        static void Main(string[] args)
        {
            Program program = new Program();
 
            program.OldMethod();
            program.NewMethod();
        }
    }
}
cs


결과 : OLD!

 NEW!

경고 : ~는 사용되지 않습니다. 'OldMethod()는 더이상 사용하지 않으므로, NewMethod()를 사용해주세요.'



* DLLImport

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
 
namespace ConsoleApplication43
{
    class Program
    {
        [DllImport("User32.dll")]
        public static extern int MessageBox(int hParent, string Messgae, string Caption, int Type);
 
        static void Main(string[] args)
        {
            MessageBox(0"DllImport!""DllImport"3);
        }
    }
}
cs


- 외부 DLL에 정의되어 있는 함수를 사용할 때에는, extern 지정자를 붙여주어야 함.






커스텀 애트리뷰트(Custom Attribute)

- 모든 애트리뷰트가 파생되는 System.Attribute 클래스를 상속받아 직접 애트리뷰트를 만들 수도 있다.

- 애트리뷰트 클래스의 멤버로 필드, 메소드, 프로퍼티, 생성자 등을 가질 수 있다.

- Conditional 특성 처럼, System.AttributeUsage를 이용하여 적용 가능한 요소값을 지정할 수 있다.


ALL : 모든 요소

Assembly : 어셈블리

Module : 모듈

Interface : 인터페이스

Class : 클래스

Struct : 구조체

Enum : 열거형

Constructor : 생성자

Method : 메소드

Property : 프로퍼티

Field : 필드

Event : 이벤트

Parameter : 메소드이 매개 변수

Delegate : 델리게이트

ReturnValue : 메소드의 반환 값


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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication43
{
    [CustomAttribute("STR", vartmp="TMP")]
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("CustomAttribute!");
        }
    }
 
    class CustomAttribute : System.Attribute
    {
        private string str;
        private string tmp;
 
        public CustomAttribute(string str)
        {
            this.str = str;
        }
 
        public string vartmp
        {
            get
            {
                return tmp;
            }
            set
            {
                tmp = value;
            }
        }
    }
}
cs

 


'NOTE > Programming' 카테고리의 다른 글

[C++] Raw String Literal  (0) 2023.11.13
[C#] abstract(추상) 클래스의 위험성.  (0) 2018.04.01
[C#] 컬렉션  (0) 2018.04.01
[C#] 예외처리  (0) 2018.04.01
[C#] 인터페이스  (0) 2018.04.01