Próbuję utworzyć typ dynamiczny na podstawie istniejącego typu zawierającego tylko pola publiczne. Nowy typ dynamiczny musi również dziedziczyć z innego typu bazowego, który ma tylko w pełni zaimplementowaną metodę.Tworzenie typu dynamicznego z TypeBuilder z klasą podstawową i dodatkowymi polami generuje wyjątek
Tworzę TypeBuilder
określając typ bazowy, a następnie dodaję do niego publiczne pola i na koniec zadzwonię pod numer CreateType()
. Otrzymany komunikat o błędzie:
„Nie można załadować typu 'InternalType' z zespołem 'MyDynamicAssembly, Version = 0.0.0.0, Culture = neutral, TokenKluczaPublicznego = null', ponieważ pole 'pierwsze' nie był podawany był wyraźne przesunięcie. "
Dla mnie oznacza to, że metoda CreateType
szuka publicznego pola "pierwszy" w klasie bazowej, co stanowi problem, ponieważ go nie ma. Dlaczego sądzi, że dodane pole powinno należeć do klasy bazowej? Czy nie rozumiem wyjątku?
Oto kod:
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;
}
Dlaczego wymagany jest 'ExplicitLayout'? – svick
svick, jest wymagany przez bibliotekę 3rd party, która używa niezarządzanego kodu do połączenia z programowalnym kontrolerem logicznym (PLC). Nie zapytałem konkretnie, być może wystarczy SequentialLayout. – dtaylor
'CreateType' zgłasza błąd:" System.TypeLoadException "w mscorlib.dll. Mówi, że mój typ ma nieprawidłowy format, dlaczego? – vulkanino