Я пытаюсь создать динамический тип на основе существующего типа, который содержит только общедоступные поля. Новый динамический тип также должен наследоваться от другого базового типа, который имеет только полностью реализованный метод.Создание динамического типа из TypeBuilder с базовым классом и дополнительными полями генерирует исключение
Я создаю TypeBuilder
, указав базовый тип, затем добавлю к нему открытые поля, и, наконец, я вызываю CreateType()
. Сообщение в результате ошибки:
«Не удалось загрузить тип 'InternalType' из сборки 'MyDynamicAssembly, Version = 0.0.0.0, культура = нейтральной, PublicKeyToken = NULL', потому что поле 'первый' не было дано явное смещение ".
Для меня это означает, что метод CreateType
ищет общедоступное поле «первым» в базовом классе, что является проблемой, потому что его нет. Почему он считает, что добавленное поле должно быть в базовом классе? Или я не понимаю исключения?
Вот код:
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;
}
Почему требуется «ExplicitLayout»? – svick
svick, требуется сторонняя библиотека, которая использует неуправляемый код для взаимодействия с программируемым логическим контроллером (PLC). Я не спрашивал конкретно, может быть, SequentialLayout хватит. – dtaylor
'CreateType' выдает мне ошибку:« System.TypeLoadException »в файле mscorlib.dll. Он говорит, что мой тип имеет недопустимый формат, почему? – vulkanino