【问题标题】:Create an instance of class by Reflection.Emmit通过 Reflection.Emit 创建一个类的实例
【发布时间】:2016-09-15 17:41:14
【问题描述】:

我正在尝试使用 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() 的调用。我做错了什么?

【问题讨论】:

  • 您是否尝试将程序集保存到磁盘并在其上运行 peverify?
  • to svick:感谢你,我发现了我的错误!

标签: c# this instance cil reflection.emit


【解决方案1】:

我明白了!这是工作代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2015-01-01
    • 1970-01-01
    • 2018-02-27
    • 2012-07-07
    • 2012-08-24
    相关资源
    最近更新 更多