[C#] string으로 함수 호출 및 매개변수 적용하기 (Reflection.MethodInfo, Action)

0시0분·2024년 8월 6일
0

C#

목록 보기
8/9

토이프로젝트를 진행하면서 대화 기능을 개발했는데
대사 텍스트 내에 키워드를 추가해 substring으로 파싱해서 사용하도록 구조를 만들었었다.

선택지 기능, 대사 마무리 후 씬 전환 등 여러 요소들을 넣고 싶었는데
해당 부분들을 모두 대사 내에 키워드로 넣고,
일일히 파싱하는 작업이 너무 비효율적이라는 생각이 들었다.

종류가 많아지다 보면 키워드를 정하는 일도 귀찮아질거고..
string을 하나씩 분해하는 것도 썩 맘에 드는 구조는 아니었다.

그러다 생각이 들었던 것이
'json 파일에 함수 이름을 지정해두고,
파싱 과정에서 해당 함수를 불러다 실행하도록 하면 깔끔하지 않을까'
였다.


1. 필요한 부분

이 아이디어를 실행하기 위해서는
1. string(데이터)으로 함수를 호출할 수 있어야 함
2. 1번으로 불러온 함수에 매개변수를 적용할 수 있어야 함

1번의 경우 MethodInfo 라는 클래스를 사용하면 가능하다.

✏️ System.Reflection.MethodInfo

✏️ System.Reflection

2번의 경우 Delegate, Func, Action 등을 사용하면 된다.

✏️ Delegate, Func, Action


2. 필요한 부분 합치기?

두 각각의 해결책을 깨닫고 나서의 고민은
'그래서 이걸 어떻게 같이 쓰지?' 였다.

2-1. 뻘짓

🎆 MethodInfo 를 통해 함수 정보를 가져오고,
이걸 Action으로 변환해서 사용하면 되겠다! 🎇

하고 생각하고서 혼자 굉장히 흡족해했다.
실제로 그렇게 사용도 했고, 결과적으로 잘 동작하긴 했다.

m_callBackFuncInfo = this.GetType().GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
f_callBackFunc = (Action<List<int>>)m_callBackFuncInfo.CreateDelegate(typeof(Action<List<int>>), this);

👀 MethodInfo to Action
https://stackoverflow.com/questions/3021578/how-can-i-create-an-action-delegate-from-methodinfo

여기서 '저 변환과정이 왜 필요하지? ' 하는 생각이 드셨다면
당신이 정답이다.

이럴 필요가 없다. 😫

2-2. ⭐ 정답 ⭐

MethodInfo를 꼼꼼히 확인하신 분들이라면 눈치채셨겠지만
이미 MethodInfo에서는 매개변수를 사용하여 호출하는 방식을 제공한다.

object MethodBase.Invoke(object obj, object[] parameters)
  • obj : 호출할 함수가 있는 객체
  • parameters : 매개변수들

헷갈렸던 부분이, 아래 함수를 호출하고자 할 때

public void SetLineIdx(List<int> vals)

object[]에 너무 매몰된 나머지
List<int> vals의 요소들을 하나씩 object 배열에 넣어야 한다고 생각했다.

그러나 이게 아니라, 아래와 같이
object[i]에 통채로 vals가 들어가야 한다.

List<object> objs = new List<object> { vals };
m_callBackFuncInfo?.Invoke(m_target, objs.ToArray());

object는 모든 클래스의 부모기 때문에 이러한 것이 가능하다.



조금 헤매긴 했지만 그래도 Action이나 여러 요소들을 제대로 써볼 수 있던 것 같아서 귀중한 시간이었다.

0개의 댓글