2016-09-15 14 views
1

System.Reflection.Emitを使用してこのC#クラスを作成しようとしています。クラスのインスタンスをReflection.Emmitで作成する

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()を作成しようとしています。このクラス自体のインスタンスを作成し、それをローカル変数に保存する方法はわかりません。私はクローン()メソッドをコールしようとしたとき、私はSystem.InvalidProgramExceptionを得る

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()を生成するためのコードです。たとえ私がメソッドCloneProperties()の呼び出しをコメントしても。私は間違っているの?

+0

アセンブリをディスクに保存しようとしましたが、その上でpeverifyが実行されましたか? – svick

+0

to svick:あなたのおかげで私の間違いが見つかりました! –

答えて

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

関連する問題