13

パブリック フィールドのみを含む既存の型に基づいて動的型を作成しようとしています。新しい動的型は、完全に実装されたメソッドのみを持つ別の基本型からも継承する必要があります。

基本型を指定してを作成し、TypeBuilderそこにパブリック フィールドを追加して、最後に を呼び出しますCreateType()。結果のエラー メッセージは次のとおりです。

「フィールド 'first' に明示的なオフセットが指定されていないため、アセンブリ 'MyDynamicAssembly、Version=0.0.0.0、Culture=neutral、PublicKeyToken=null' から型 'InternalType' を読み込めませんでした。」

私にとって、これは、CreateTypeメソッドが基本クラスの public フィールドを「最初に」探していることを意味します。これは、そこにないため問題です。追加されたフィールドが基本クラスにある必要があると考えるのはなぜですか? または、例外を誤解していますか?

コードは次のとおりです。

public class sourceClass
{
    public Int32 first = 1;
    public Int32 second = 2;
    public Int32 third = 3;
}

public static class MyConvert
{
    public static object ToDynamic(object sourceObject, out Type outType)
    {
        // get the public fields from the source object
        FieldInfo[] sourceFields = sourceObject.GetType().GetFields();

        // get a dynamic TypeBuilder and inherit from the base type
        AssemblyName assemblyName
            = new AssemblyName("MyDynamicAssembly");
        AssemblyBuilder assemblyBuilder
            = AppDomain.CurrentDomain.DefineDynamicAssembly(
                assemblyName,
                AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder
            = assemblyBuilder.DefineDynamicModule("MyDynamicModule");
        TypeBuilder typeBuilder
            = moduleBuilder.DefineType(
                "InternalType",
                TypeAttributes.Public
                | TypeAttributes.Class
                | TypeAttributes.AutoClass
                | TypeAttributes.AnsiClass
                | TypeAttributes.ExplicitLayout,
                typeof(SomeOtherNamespace.MyBase));

        // add public fields to match the source object
        foreach (FieldInfo sourceField in sourceFields)
        {
            FieldBuilder fieldBuilder
                = typeBuilder.DefineField(
                    sourceField.Name,
                    sourceField.FieldType,
                    FieldAttributes.Public);
        }

        // THIS IS WHERE THE EXCEPTION OCCURS
        // create the dynamic class
        Type dynamicType = typeBuilder.CreateType();

        // create an instance of the class
        object destObject = Activator.CreateInstance(dynamicType);

        // copy the values of the public fields of the
        // source object to the dynamic object
        foreach (FieldInfo sourceField in sourceFields)
        {
            FieldInfo destField
                = destObject.GetType().GetField(sourceField.Name);
            destField.SetValue(
                destObject,
                sourceField.GetValue(sourceField));
        }

        // give the new class to the caller for casting purposes
        outType = dynamicType;

        // return the new object
        return destObject;
    }
4

1 に答える 1