게임을 하고 있는 런타임 중에도 새로운 직업 클래스를 동적으로 만들어 적용할 수 있도록 한다.
아직 IL 명령어에 대한 이해가 깊지 않아 아래 예시 코드는 단순 계산 메소드만이 만들어져 있지만, 앞으로 미리 만들어져 있는 메소드의 주소를 IL 명령어로 받아 사용할 수 있게 된다면 게임 중에도 새로운 직업을 만드는 등의 자유로운 게임의 구현이 가능하지 않을까 상상해본다.
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace NewJob
{
class MainApp
{
public static void Main()
{
AssemblyBuilder newAssembly = AssemblyBuilder.DefineDynamicAssembly
(new AssemblyName("NewJobAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder newModule = newAssembly.DefineDynamicModule("NewJob");
TypeBuilder newType = newModule.DefineType("Calculator");
MethodBuilder newMethodOne = newType.DefineMethod(
"Sum1To100",
MethodAttributes.Public,
typeof(int), // 반환 형식
new Type[0]); // 매개변수
ILGenerator generatorOne = newMethodOne.GetILGenerator();
generatorOne.Emit(OpCodes.Ldc_I4, 1);
for (int i = 2; i <= 100; ++i)
{
generatorOne.Emit(OpCodes.Ldc_I4, i);
generatorOne.Emit(OpCodes.Add);
}
generatorOne.Emit(OpCodes.Ret);
MethodBuilder newMethodTwo = newType.DefineMethod(
"Multiply1To10",
MethodAttributes.Public,
typeof(int), // 반환 형식
new Type[0]); // 매개변수
ILGenerator generatorTwo = newMethodTwo.GetILGenerator();
generatorTwo.Emit(OpCodes.Ldc_I4, 1);
for (int i = 2; i <= 10; ++i)
{
generatorTwo.Emit(OpCodes.Ldc_I4, i);
generatorTwo.Emit(OpCodes.Mul);
}
generatorTwo.Emit(OpCodes.Ret);
newType.CreateType();
object calculater = Activator.CreateInstance(newType);
MethodInfo Sum1To100 = calculater.GetType().GetMethod("Sum1To100");
Console.WriteLine(Sum1To100.Invoke(calculater, null));
MethodInfo Multiply1To10 = calculater.GetType().GetMethod("Multiply1To10");
Console.WriteLine(Multiply1To10.Invoke(calculater, null));
}
}
}