게임을 하고 있는 런타임 중에도 새로운 직업 클래스를 동적으로 만들어 적용할 수 있도록 한다.

아직 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));
        }
    }
}