0
누군가가 첫 번째 테스트에서 다음과 같은 이유가 설명되어 있지만 두 번째 테스트에서 InvalidProgramException이 발생합니다. 나는 혼란 스럽다. 동적 방법은 New<T>
버전의 매개 변수를 가지고 있지 않기 때문에JIT 컴파일러 오류 - Reflection.Emit를 사용하는 잘못된 프로그램 예외
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace DMTest { class Program { static void Main(string[] args) { Test.NewResultWithParam(); Console.WriteLine("Press any key to continue"); Console.ReadLine(); Test.NewResult(); Console.WriteLine("Press any key to exit"); Console.ReadLine(); } }
public static class Test
{
public static void NewResult()
{
var f = typeof(Result).New<Result>();
var result = f.Invoke();
}
public static void NewResultWithParam()
{
var f = typeof(Result).New<Param, Result>();
var result = f.Invoke(new Param("Parameter Executed"));
result.Build();
}
}
public static class DynamicFunctions
{
public static Func<R> New<R>(this Type type)
{
if (!typeof(R).IsAssignableFrom(type))
{
throw new ArgumentException();
}
var dm = BuildNewMethod(type, Type.EmptyTypes);
return (Func<R>)dm.CreateDelegate(typeof(Func<R>));
}
public static Func<T, R> New<T, R>(this Type type)
{
if (!typeof(R).IsAssignableFrom(type))
{
throw new ArgumentException();
}
var dm = BuildNewMethod(type, new Type[] { typeof(T) });
return (Func<T, R>)dm.CreateDelegate(typeof(Func<T, R>));
}
private static DynamicMethod BuildNewMethod(Type newObjType, Type[] parameterTypes)
{
var dm = new DynamicMethod("New_" + newObjType.FullName, newObjType, parameterTypes, newObjType);
var info = newObjType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, parameterTypes, new ParameterModifier[0]);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, info);
il.Emit(OpCodes.Ret);
return dm;
}
}
public class Result
{
private Param _param;
private Result()
{
Console.WriteLine("Parameterless constructor called");
}
private Result(Param param)
{
Console.WriteLine("Parametered constructor called");
_param = param;
}
public void Build()
{
_param.Execute();
}
}
public class Param
{
private string _s;
public Param(string s)
{
_s = s;
}
public void Execute()
{
Console.WriteLine(_s);
}
}
}
수정 됨. 고맙습니다. 나는 그것이 내가 잃어버린 단순한 것이라고 생각했다. –