我正在尝试使用System.Reflection.Emit创建此C#类。
private class MyTestData : IMyClonable
{
private int _testValue = 0;
public int testValue
{
get { return _testValue; }
set { _testValue = value; }
}
public IMyClonable Clone()
{
MyTestData clone = new MyTestData();
clone._testValue = _testValue;
return clone ;
}
}
必须从此界面创建此类:
public interface IMyTestData : IMyClonable
{
int testValue { get; set; }
}
我已经制作了生成属性的代码,这项工作很好。但是当我尝试创建方法Clone()时,我卡住了。我不知道如何创建这个类本身的实例并将其保存在局部变量中。 以下是生成方法Clone()的代码:
private static void MakeCloneMethod(Type componentType, TypeBuilder typeBuilder)
{
ConstructorBuilder ctor =
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
MethodInfo cloneMethod = typeof(IMyClonable).GetMethod("Clone");
MethodAttributes methodIlAttributes =
(cloneMethod.Attributes & ~MethodAttributes.Abstract) | MethodAttributes.Final;
MethodBuilder cloneMthdBldr = typeBuilder.DefineMethod(
"Clone", methodIlAttributes, typeof(IMyClonable), new Type[] { });
ILGenerator ilgen = cloneMthdBldr.GetILGenerator();
LocalBuilder returnValue = ilgen.DeclareLocal(typeBuilder.AsType());
ilgen.Emit(OpCodes.Newobj, ctor);
ilgen.Emit(OpCodes.Stloc_S, returnValue);
CloneProperties(componentType, ilgen);
ilgen.Emit(OpCodes.Ldloc_S);
ilgen.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(cloneMthdBldr, cloneMethod);
}
private static void CloneProperties(Type componentType, ILGenerator ilgen)
{
PropertyInfo[] allProperties = GetPublicProperties(componentType);
foreach (PropertyInfo propInfo in allProperties)
{
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Ldfld, builders[propInfo]);
ilgen.Emit(OpCodes.Stfld, builders[propInfo]);
ilgen.Emit(OpCodes.Ldloc_0);
}
}
当我尝试调用Clone()方法时,我得到了System.InvalidProgramException。即使我评论方法CloneProperties()的调用。我做错了什么?
答案 0 :(得分:0)
我明白了!这是工作代码:
private static void MakeCloneMethod(Type componentType, TypeBuilder typeBuilder)
{
Type thisType = typeBuilder.AsType();
Type itype = typeof(IMyClonable);
MethodInfo cloneMthd = itype.GetMethod("Clone");
MethodBuilder cloneMthdBldr = typeBuilder.DefineMethod(
cloneMthd.Name, cloneMthd.Attributes & ~MethodAttributes.Abstract,
itype, new Type[] {});
typeBuilder.DefineMethodOverride(cloneMthdBldr, cloneMthd);
ILGenerator gen = cloneMthdBldr.GetILGenerator();
LocalBuilder returnValue = gen.DeclareLocal(thisType);
gen.Emit(OpCodes.Newobj, typeBuilder.DefineDefaultConstructor(MethodAttributes.Public));
gen.Emit(OpCodes.Stloc_S, returnValue);
PropertyInfo[] allProperties = GetPublicProperties(componentType);
foreach (PropertyInfo propInfo in allProperties)
{
gen.Emit(OpCodes.Ldloc_S, returnValue);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, builders[propInfo]);
gen.Emit(OpCodes.Stfld, builders[propInfo]);
}
gen.Emit(OpCodes.Ldloc_S, returnValue);
gen.Emit(OpCodes.Ret);
}
感谢Svick!