📒 갈무리 - Reflection & Attributes
📌 Reflection이란?
- 프로그램 실행 중에 객체의 정보를 얻거나, 다른 모듈에 선언된 인스턴스를 생성하거나, 기존 개체에서 형식을 가져오고 해당하는 메소드를 호출, 또는 해당 필드와 속성에 접근할 수 있는 기능을 제공한다.
- 인 게임에서 사용하기보다, 툴이나 에디터 상에서 데이터 처리할 때 사용
📌 GetType & typeof
GetType : 런타임 시점의 Object를 상속받는 객체 인스턴스의 Type을 알려준다.
typeof : 컴파일 시점의 클래스 자체의 Type을 알려준다.
📌 Reflection 예제
class MyClass
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
SetDefaultName(myClass);
Console.WriteLine("MyClass Name : " + myClass.Name);
}
static void SetDefaultName(Object myObject)
{
PropertyInfo propertyInfo = myObject.GetType().GetProperty("Name");
if (propertyInfo != null)
{
propertyInfo.SetValue(myObject, "Kim");
}
}
}
Output:
MyClass Name : Kim
📌 클래스 정보 얻어오기
class Class1
{
public void Run()
{
Type customerType = Type.GetType("MyNamespace.Customer");
Object obj = Activator.CreateInstance(customerType);
string name = ((Customer)obj).Name;
Console.WriteLine(name);
}
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public Customer()
{
this.Name = "None";
}
}
📌 Attributes란?
- 메타데이터를 추가할 수 있는 기능을 제공한다.
- 클래스, 메소드, 구조체, 생성자, 프로퍼티, 필드, 이벤트, 인터페이스 등 여러 가지 요소에 Attributes를 사용할 수 있다.
- 주석은 개발자가 참고하기 위해 사용하는 것이며 런타임 때는 전혀 고려되지 않지만, Attributes는 컴퓨터가 런타임에 참고하기 위해 사용되는 주석과 같은 존재이며 컴퓨터가 런타임 중에도 Attributes가 붙은 대상을 체크하여 그에 관한 작업을 진행한다.
- 특성을 찾고 작업을 수행하는 것은 모두 C# 컴파일러가 진행한다.
- 코드에 대한 정보 혹은 데이터를 말한다.
📌 Attributes 예제
public class AttributesEX
{
[Obsolete("이 메소드는 더 이상 사용되지 않습니다.")]
public static int Add(int a, int b)
{
return (a + b);
}
}
사용자 지정 Attributes
class DeveloperAttribute : Attribute
{
private string name;
private string level;
private bool reviewed;
public DeveloperAttribute(string name, string level)
{
this.name = name;
this.level = level;
this.reviewed = false;
}
public virtual string Name
{
get { return name; }
}
public virtual string Level
{
get { return level; }
}
public virtual bool Reviewed
{
get { return reviewed; }
set { reviewed = value; }
}
}
[Developer("Kang", "20", Reviewed = true)]
class Program
{
static void Main(string[] args)
{
GetAttribute(typeof(Program));
}
public static void GetAttribute(Type t)
{
DeveloperAttribute developerAttribute =
(DeveloperAttribute)Attribute.GetCustomAttribute(t, typeof(DeveloperAttribute));
if(developerAttribute == null)
{
Console.WriteLine("해당 Attribute를 찾을 수 없습니다.");
return;
}
Console.WriteLine("name of developerAttribute : " + developerAttribute.Name);
Console.WriteLine("Level of developerAttribute : " + developerAttribute.Level);
Console.WriteLine("Reviewed of developerAttribute : " + developerAttribute.Reviewed);
}
}
Reflection과 Attributes
class Important : Attribute
{
string message;
public Important(string message)
{
this.message = message;
}
}
class Monster
{
[Important("very important")]
public int hp;
protected int attck;
private float speed;
}
class Program
{
static void Main(string[] args)
{
Monster monster = new Monster();
Type type = monster.GetType();
FieldInfo[] fields = type.GetFields();
var attribute = fields[0].GetCustomAttributes();
}
}