系统反射 IL 发出覆盖方法语法
System reflection IL emit override method syntax
我想在下面生成的代码中正确覆盖 ToString()。我的 ToString 应该 return _value 字段的内容。
我很难找到正确覆盖它的语法 - 这是我当前的代码:
static public Type BuildType() {
AppDomain domain = Thread.GetDomain();
AssemblyName assemblyName = new AssemblyName {Name = "DynamicDataGridDataAsm"};
AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.RunAndSave);
ModuleBuilder dynamicDataGridDataModule = assemblyBuilder.DefineDynamicModule("DynamicDataGridDataModule", "DynamicDataGridDataModule.dll");
TypeBuilder ivTypeBld = dynamicDataGridDataModule.DefineType("DynamicDataGridData", TypeAttributes.Public);
FieldBuilder field = ivTypeBld.DefineField("_value", typeof(string), FieldAttributes.Public);
MethodBuilder getValue = ivTypeBld.DefineMethod("ToString",
MethodAttributes.Public ,
CallingConventions.Standard,
typeof(string),
Type.EmptyTypes);
ILGenerator il = getValue.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, field);
il.Emit(OpCodes.Ret);
return ivTypeBld.CreateType();
}
我目前正在对象上显式调用此方法,但我假设如果我正确覆盖它,那么我(和框架)可以使用点运算符调用它并执行我的实现。
阅读更多内容并查看更多示例后,这些参数和调用似乎正确覆盖了对象的 ToString() 方法:
FieldBuilder field = ivTypeBld.DefineField("_value", typeof(string), FieldAttributes.Public);
MethodBuilder toStringMethod = ivTypeBld.DefineMethod("ToString",
MethodAttributes.Public
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.Virtual
| MethodAttributes.Final,
CallingConventions.HasThis,
typeof(string),
Type.EmptyTypes);
ILGenerator il = toStringMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, field);
il.Emit(OpCodes.Ret);
ivTypeBld.DefineMethodOverride(toStringMethod, typeof(object).GetMethod("ToString"));
有更好的信息可用,但为了帮助任何正在寻找的人,属性规定新函数是 public,通过名称和签名隐藏基础 class 成员,占用一个新的 vtable 槽,是最终的,将在实例上调用(不是静态函数 - HasThis)。
我还没有研究 'NewSlot' 是否或为什么是必要的,或者它对这个方法定义意味着什么。
我想在下面生成的代码中正确覆盖 ToString()。我的 ToString 应该 return _value 字段的内容。
我很难找到正确覆盖它的语法 - 这是我当前的代码:
static public Type BuildType() {
AppDomain domain = Thread.GetDomain();
AssemblyName assemblyName = new AssemblyName {Name = "DynamicDataGridDataAsm"};
AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.RunAndSave);
ModuleBuilder dynamicDataGridDataModule = assemblyBuilder.DefineDynamicModule("DynamicDataGridDataModule", "DynamicDataGridDataModule.dll");
TypeBuilder ivTypeBld = dynamicDataGridDataModule.DefineType("DynamicDataGridData", TypeAttributes.Public);
FieldBuilder field = ivTypeBld.DefineField("_value", typeof(string), FieldAttributes.Public);
MethodBuilder getValue = ivTypeBld.DefineMethod("ToString",
MethodAttributes.Public ,
CallingConventions.Standard,
typeof(string),
Type.EmptyTypes);
ILGenerator il = getValue.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, field);
il.Emit(OpCodes.Ret);
return ivTypeBld.CreateType();
}
我目前正在对象上显式调用此方法,但我假设如果我正确覆盖它,那么我(和框架)可以使用点运算符调用它并执行我的实现。
阅读更多内容并查看更多示例后,这些参数和调用似乎正确覆盖了对象的 ToString() 方法:
FieldBuilder field = ivTypeBld.DefineField("_value", typeof(string), FieldAttributes.Public);
MethodBuilder toStringMethod = ivTypeBld.DefineMethod("ToString",
MethodAttributes.Public
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.Virtual
| MethodAttributes.Final,
CallingConventions.HasThis,
typeof(string),
Type.EmptyTypes);
ILGenerator il = toStringMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, field);
il.Emit(OpCodes.Ret);
ivTypeBld.DefineMethodOverride(toStringMethod, typeof(object).GetMethod("ToString"));
有更好的信息可用,但为了帮助任何正在寻找的人,属性规定新函数是 public,通过名称和签名隐藏基础 class 成员,占用一个新的 vtable 槽,是最终的,将在实例上调用(不是静态函数 - HasThis)。
我还没有研究 'NewSlot' 是否或为什么是必要的,或者它对这个方法定义意味着什么。