在运行时实现接口:get_Value方法未实现
我试图在运行时定义一个从已知类继承并实现接口的类型。
public class ParentClass
{
}
public interface IImplementMe
{
double Value{get;set}
}
这是显示我如何尝试实现目标的代码片段。
public class ClassBuilder
{
public Type Build()
{
try
{
AssemblyName assemblyName = new AssemblyName("DataBuilderAssembly");
AssemblyBuilder assemBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemBuilder.DefineDynamicModule("DataBuilderModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType("NewClass", TypeAttributes.Class, typeof(ParentClass));
typeBuilder.AddInterfaceImplementation(typeof(IImplementMe));
BuildProperty(typeBuilder, "Value", typeof(double));
Type type = typeBuilder.CreateType();
return type;
}
catch (Exception e)
{
return null;
}
}
private void BuildProperty(TypeBuilder typeBuilder, string name, Type type)
{
FieldBuilder field = typeBuilder.DefineField("m" + name, type, FieldAttributes.Private);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.None, type, null);
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
MethodBuilder getter = typeBuilder.DefineMethod("get_" + name, getSetAttr, type, Type.EmptyTypes);
ILGenerator getIL = getter.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, field);
getIL.Emit(OpCodes.Ret);
MethodBuilder setter = typeBuilder.DefineMethod("set_" + name, getSetAttr, null, new Type[] { type });
ILGenerator setIL = setter.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, field);
setIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getter);
propertyBuilder.SetSetMethod(setter);
}
}
由于某种原因,我在调用 typeBuilder.CreateType() 时收到“get_Value 方法未实现”异常。目前还看不出其背后的原因。
I was trying to define a type at run-time that inherits from a known class and implements an interface.
public class ParentClass
{
}
public interface IImplementMe
{
double Value{get;set}
}
Here's the code snippet that shows how I try to achieve my goal.
public class ClassBuilder
{
public Type Build()
{
try
{
AssemblyName assemblyName = new AssemblyName("DataBuilderAssembly");
AssemblyBuilder assemBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemBuilder.DefineDynamicModule("DataBuilderModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType("NewClass", TypeAttributes.Class, typeof(ParentClass));
typeBuilder.AddInterfaceImplementation(typeof(IImplementMe));
BuildProperty(typeBuilder, "Value", typeof(double));
Type type = typeBuilder.CreateType();
return type;
}
catch (Exception e)
{
return null;
}
}
private void BuildProperty(TypeBuilder typeBuilder, string name, Type type)
{
FieldBuilder field = typeBuilder.DefineField("m" + name, type, FieldAttributes.Private);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.None, type, null);
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
MethodBuilder getter = typeBuilder.DefineMethod("get_" + name, getSetAttr, type, Type.EmptyTypes);
ILGenerator getIL = getter.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldfld, field);
getIL.Emit(OpCodes.Ret);
MethodBuilder setter = typeBuilder.DefineMethod("set_" + name, getSetAttr, null, new Type[] { type });
ILGenerator setIL = setter.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, field);
setIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getter);
propertyBuilder.SetSetMethod(setter);
}
}
For some reason I get an "get_Value method not implemented" exception on calling typeBuilder.CreateType()
. So far unable to see the reason behind it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C# 隐式接口实现(通过名称匹配)只是为了方便;手动执行此操作时,您需要使用 typeBuilder.DefineMethodOverride 将虚拟方法表中的每个方法关联起来,传入新的(生成的)方法和接口方法来满足。必须对要实现的每个接口的每个方法执行此操作。
The c# implicit interface implementation (by name match) is convenience only; when doing it by hand you need to associate each in the virtual-method table using typeBuilder.DefineMethodOverride, passing in the new (generated) method and the interface method to satisfy. This must done for each method of every interface you want to implement.
将您的行更改为:
然后您的代码对我有用。 (需要虚拟。)
Changing your line to:
Your code then worked for me. (The virtual was required.)
您需要将其标记为虚拟,并将实现显式绑定到接口:
You need to mark it as virtual, and explicitly bind the implementation to the interface: