리플렉션이란 프로그램이 실행되는 동안 자신의 구조를 검사하고 수정할 수 있는 기능을 의미합니다. 런타임에 대한 정보를 얻고 동적으로 조작할 수 있게 해줍니다.
System.Reflaction
이 네임스페이스는 리플렉션 관련 클래스와 메서드를 포함하고 있습니다.
using System;
public class MyClass
{
public int MyProperty { get; set; }
public void MyMethod()
{
Console.WriteLine("MyMethod called");
}
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
// 클래스 이름 출력
Console.WriteLine("Class Name: " + type.Name);
// 속성 정보 출력
foreach (var prop in type.GetProperties())
{
Console.WriteLine("Property: " + prop.Name);
}
// 메서드 정보 출력
foreach (var method in type.GetMethods())
{
Console.WriteLine("Method: " + method.Name);
}
}
}
타입 정보를 조회하면 그 메서드에 있는 메타데이터나 상태를 알 수 있다.
GetProperties() : 해당 타입의 모든 속성 정보를 배열 형태로 반환한다. 속성은 클래스의 데이터 멤버로, 일반적으로 get, set 접근자를 통해 값을 읽고 쓸 수 있다.(get과 set이 없는 속성은 일반적으로 존재X)
GetMethods() : 해당 타입의 모든 메서드(Method) 정보를 배열 형태로 반환한다. 메서드는 클래스의 동작을 정의하는 함수로, 특정 작업을 수행한다.
using System;
using System.Reflection;
public class MyClass
{
public void SayHello()
{
Console.WriteLine("Hello, World!");
}
}
class Program
{
static void Main()
{
MyClass myObject = new MyClass();
Type type = myObject.GetType();
// SayHello 메서드 정보 가져오기
MethodInfo methodInfo = type.GetMethod("SayHello", Type.EmptyTypes)!;
if (methodInfo == null)
{
Console.WriteLine("메서드를 찾을 수 없습니다.");
return;
}else{
// 메서드 호출
methodInfo.Invoke(myObject, null);
}
}
}
GetType()메서드는 typeof()와는 다르게 해당 객체의 런타임 타입 정보를 가져온다.
GetMethod()는 특정 이름을 가진 단일 메서드의 정보를 반환한다.
GetMethod(,,,)은 null을 반환할 수 있기 때문에 null인지 확인하는 조건문이 필요하고, 경고 문구가 나오게 된다. 경고 문구는 "!"를 통해 명시적으로 null이 나오지 않는다고 컴파일러에게 알린다.
using System;
using System.Reflection;
public class MyClass
{
public int MyProperty { get; set; }
}
class Program
{
static void Main()
{
MyClass myObject = new MyClass();
Type type = myObject.GetType();
// 속성 정보 가져오기
PropertyInfo propertyInfo = type.GetProperty("MyProperty");
// 속성 값 설정
propertyInfo.SetValue(myObject, 42);
// 속성 값 가져오기
int value = (int)propertyInfo.GetValue(myObject);
Console.WriteLine("MyProperty: " + value);
}
}
using System;
using System.Reflection;
using UnityEngine;
public class ReflectionExample : MonoBehaviour
{
void Start()
{
// 호출할 메서드 이름과 매개변수
string methodName = "MyMethod";
object[] parameters = { 42, "Hello" }; // 예시 매개변수
// 메서드 호출
CallMethod(methodName, parameters);
}
void CallMethod(string methodName, object[] parameters)
{
// 현재 클래스의 Type 가져오기
Type type = this.GetType();
// 메서드 정보 가져오기
MethodInfo methodInfo = type.GetMethod(methodName);
if (methodInfo != null)
{
// 메서드 호출
methodInfo.Invoke(this, parameters);
}
else
{
Debug.LogError($"Method '{methodName}' not found.");
}
}
// 예시 메서드 (매개변수 있음)
public void MyMethod(int number, string message)
{
Debug.Log($"MyMethod called with number: {number} and message: {message}");
}
}
이런식으로 특정 문자열과 같은 이름을 가진 메서드를 실행시킬 수 있다.
내가 사용했던 방식을 설명하자면
+) 사실 Invoke()만 써도 이름을 통해 메서드 실행이 가능하다...
+) 리플렉션은 직접 인스펙터나 에디터 도구를 만들때, 동적으로 객체의 정보를 가져올때 효율적으로 작동할 수 있다.