C# 如何在反射发射类中发射局部变量init([0]字符串V_0)?
它会在此行中引发异常:C# 如何在反射发射类中发射局部变量init([0]字符串V_0)?,c#,.net,reflection.emit,C#,.net,Reflection.emit,它会在此行中引发异常: s = method.Invoke(student, new object[] { "pig" }); 下面是完整的代码,您可以创建一个新的.net framewrok控制台应用程序并运行它 public class Program { static void Main(string[] args) { MethodInfo method = typeof(Student).GetMet
s = method.Invoke(student, new object[] { "pig" });
下面是完整的代码,您可以创建一个新的.net framewrok控制台应用程序并运行它
public class Program
{
static void Main(string[] args)
{
MethodInfo method = typeof(Student).GetMethod("SayHello");
var student1 = new Student("lucy");
object s = method.Invoke(student1, new object[] { "pig" });
var student = BuildType(typeof(Person));
//todo:throw an exception here ??
s = method.Invoke(student, new object[] { "pig" });
Console.ReadKey();
}
public static object BuildType(Type baseType)
{
AppDomain dom = AppDomain.CurrentDomain;
AssemblyName asmName = new AssemblyName("DynamicAssembly");
AssemblyBuilder assemblyBuilder = dom.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
//AssemblyName DemoName = new AssemblyName("DynamicAssembly");
//AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(DemoName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("LjxModule", "LjxModule.dll");
//dynamicly create Class
TypeBuilder tb = moduleBuilder.DefineType("MyStudent", TypeAttributes.Public, baseType);
Type[] ctorPaTypes = new Type[] { typeof(string) };
ConstructorBuilder ctorBuilder = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard | CallingConventions.HasThis, ctorPaTypes);
ILGenerator msilGenerator = ctorBuilder.GetILGenerator();
msilGenerator.Emit(OpCodes.Ldarg_0);//push this
msilGenerator.Emit(OpCodes.Ldarg_1);
ConstructorInfo baseCtor = baseType.GetConstructor(ctorPaTypes);
if (baseCtor == null)
{
throw new Exception("some exception!");
}
msilGenerator.Emit(OpCodes.Call, baseCtor);
msilGenerator.Emit(OpCodes.Nop);
msilGenerator.Emit(OpCodes.Nop);
msilGenerator.Emit(OpCodes.Ret);
//override method
MethodBuilder executeAsyncMethod = tb.DefineMethod("SayHello", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(string),
new Type[] { typeof(object) });
MethodInfo baseMethodInfo = baseType.GetMethod("SayHello", new Type[] { typeof(object) });
if (baseMethodInfo == null)
{
throw new Exception("some exception!");
}
ILGenerator ilGen = executeAsyncMethod.GetILGenerator();
var mylabel = ilGen.DefineLabel();
//todo:this line code emit: .locals init (string[] V_0)
//but i found Student class' il is: .locals init ([0] string V_0)
var v1 = ilGen.DeclareLocal(typeof(string));
ilGen.Emit(OpCodes.Nop);
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Ldarg_1);
ilGen.Emit(OpCodes.Call, baseMethodInfo);
ilGen.Emit(OpCodes.Stloc_0);
ilGen.Emit(OpCodes.Br_S, mylabel);
ilGen.MarkLabel(mylabel);
ilGen.Emit(OpCodes.Ldloc_0);
ilGen.Emit(OpCodes.Ret);
if (baseMethodInfo == null)
{
throw new Exception("some exception!");
}
//tb.DefineMethodOverride(executeAsyncMethod, baseMethodInfo);
Type resultType = tb.CreateType();
//save dll
assemblyBuilder.Save("LjxModule.dll");
//create instance
var arg0 = "jacks";
if (resultType == null)
{
throw new Exception("some exception!");
}
return Activator.CreateInstance(resultType, arg0);
}
public static Type SingleTypeByQualifiedName(string assemblyQualifiedName)
{
Type paramType = Type.GetType(assemblyQualifiedName);
if (paramType == null)
{
throw new Exception($"not found {assemblyQualifiedName}!");
}
return paramType;
}
}
public class Person
{
public Person(string name)
{
Name = name;
}
public string Name { get; set; }
public virtual string SayHello(object obj)
{
return Name + "say:" + obj.ToString();
}
}
public class Student : Person
{
public Student(string name) : base(name)
{
}
public override string SayHello(object obj)
{
return base.SayHello(obj);
}
}
这是发射的IL:
.method public hidebysig virtual instance string SayHello(object A_1) cil managed
{
// 代码大小 13 (0xd)
.maxstack 3
.locals init (string[] V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: call instance string [DotFxConsoleApp1]DotFxConsoleApp1.Model.Person::SayHello(object)
IL_0008: stloc.0
IL_0009: br.s IL_000b
IL_000b: ldloc.0
IL_000c: ret
} // end of method MyStudent::SayHello
这是学生班的IL
.method public hidebysig virtual instance string SayHello(object obj) cil managed
{
// 代码大小 13 (0xd)
.maxstack 2
.locals init ([0] string V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: call instance string DotFxConsoleApp1.Model.Person::SayHello(object)
IL_0008: stloc.0
IL_0009: br.s IL_000b
IL_000b: ldloc.0
IL_000c: ret
} // end of method Student::SayHello
看起来唯一的区别是.locals init(string[]V_0),如何修复它?谁能帮我一下吗?多谢各位 我知道原因。我犯了一个错误。我使用Student.SayHello MethodInfo调用MyStudent实例。我已经更正了代码,现在它运行良好
MethodInfo method = typeof(Student).GetMethod("SayHello");
var student1 = new Student("lucy");
object s = method.Invoke(student1, new object[] { "pig" });
var myStuType = BuildType(typeof(Person));
MethodInfo dyMethod = myStuType.GetMethod("SayHello");
var student = Activator.CreateInstance(myStuType, new string[] { "jack" });
s = dyMethod.Invoke(student, new object[] { "pig" });
这并不重要,但最好是执行
ilGen.Emit(OpCodes.Stloc,v1)代码>,而不是猜测插槽的编号。试一试,看看它是否有任何区别。你有哪个版本的.NET?谢谢你的canton7和Charlieface。我知道原因。我犯了一个错误