C#과 유니티로 만드는 MMORPG 게임 개발 시리즈 강의를 수강하며 리플렉션 파트에서 배우고 느낀 점을 정리해보았다.
- 리플렉션이란
- 클래스가 가지고 있는 모든 정보들을 Runtime중에 뜯어보고 분석해볼 수 있는, 일종의 X-Ray라고 할 수 있다. - 사용 예제
using System.Reflection;
namespace CSharpStudy
{
class Program
{
class Monster
{
public int hp;
protected int attack;
private float speed;
void Attack() { }
}
static void Main(string[] args)
{
Monster monster = new Monster();
Type type = monster.GetType();
// C#의 모든 객체들은 Object에서 파생되기 때문에 GetType이란걸 들고있다.
// 이걸 이용하면 객체의 타입을 빼낼 수 있다.
// 이 type을 사용하면 클래스의 이름부터 내부 변수, 함수까지
// 모든 정보를 알 수 있다.
var fields = type.GetFields(System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Static
| System.Reflection.BindingFlags.Instance); // 지정한 정보들을 내뱉게 됨
foreach (FieldInfo field in fields)
{ // 필드에 있는 정보를 추출해서 정보를 얻을 수 있다.
string access = "protected";
if (field.IsPublic)
access = "public";
else if (field.IsPrivate)
access = "private";
Console.WriteLine($"{access} {field.FieldType.Name} {field.Name}");
}
}
}
}
이 밖에도 프로퍼티나 필드, 생성자 정보를 얻는 등 클래스 내부의 다양한 정보에 대해서 알 수 있다.
- 애트리뷰트란?
- 클래스나 메소드의 메타데이터를 기록할 수 있는 기능. 프로그래머끼리 정보를 전달할 수 있지만 컴퓨터는 사용할 수 없는 일반 주석과 달리 컴퓨터가 runtime중에도 체크하고 참고할 수 있는 힌트를 남길 수 있다. - 애트리뷰트 사용 예제
class Program
{
class Important : System.Attribute
{
string massage;
public Important(string massage) { this.massage = massage; }
}
class Monster
{
// hp입니다. 중요한 정보입니다. -> 이렇게 기록해도 컴퓨터는 인식하지 않음
[Important("Very Important")] // 애트리뷰트에서 파생된 클래스를 선언함으로서 컴퓨터가 체크하게 됨
public int hp;
protected int attack;
private float speed;
void Attack() { }
}
static void Main(string[] args)
{
Monster monster = new Monster();
Type type = monster.GetType();
var fields = type.GetFields(System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Static
| System.Reflection.BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
string access = "protected";
if (field.IsPublic)
access = "public";
else if (field.IsPrivate)
access = "private";
var attributes = field.GetCustomAttributes();
Console.WriteLine($"{access} {field.FieldType.Name} {field.Name}");
}
}
}
- 리플렉션과 애트리뷰트는 툴을 만들 때 특히 유용하다.
- 예를 들어서 유니티에서 public 상태로 변수를 입력하면 바로 인스펙터창에 해당 변수가 나타나는데, 이를 리플렉션 기능 없이 구현하려면 상당히 어려워질 것이다.
언리얼의 경우 C++에 리플렉션 기능이 없기 때문에 파일을 읽어와서 필드로 추정되는 값을 어딘가에 기억하도록 다른 파일을 이용해 간접적으로 관리하도록 만들게 되는데,
C#은 자체적으로 리플렉션을 지원하므로 필드의 값을 바로 체크하여 툴의 UI를 열어주게끔 구현할 수 있다.
엑셀을 참고해 무언가를 동적으로 구현할 때도 유용하게 쓸 수 있다.
- 유니티에서 private 변수의 값을 인스펙터에 나타내주는 SerializeField 키워드도 애트리뷰트인 일종인 주석 문법이다.
'C#' 카테고리의 다른 글
220823 Nullable (널러블) (0) | 2022.08.23 |
---|---|
220822 Exception (예외 처리) (0) | 2022.08.22 |
220822 Event (이벤트) (0) | 2022.08.22 |
[C#] Delegate (대리자) (0) | 2022.08.21 |
220820 Property (프로퍼티) + 식 본문 멤버 (Expression-bodied members) (0) | 2022.08.20 |