Мне нужно создать тип во время выполнения, используя TypeBuilder.Этот тип должен реализовывать определенный интерфейс, чтобы можно было обрабатывать экземпляры этого динамического типа равномерно во время компиляции.
Интерфейс должен возвращать массив объектов, заполненных значениями определенных полей этого типа.
Интерфейс, который предполагается реализовать, определяется следующим образом:
public interface ISelectable
{
object[] GetPrimaryKeysValues();
}
Этот код я использую для генерации метода для интерфейса:
public static Type BuildTypeFromTable(Table tableToBuildTypeFrom)
{
AssemblyBuilder customTypesAssembly =
AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("CustomTypesAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder _moduleBuilder = customTypesAssembly.DefineDynamicModule("CustomTypesModule");
TypeBuilder customTypeBuilder = _moduleBuilder.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Public | TypeAttributes.Class);
List<FieldBuilder> primaryKeyFields = new List<FieldBuilder>();
//create a property for each column in the table
for (int i = 0; i < tableToBuildTypeFrom.Columns.Count; i++)
{
string propertyName = tableToBuildTypeFrom.Columns[i].Name;
//get a type of a property to create from a first row of the table
Type propertyType = tableToBuildTypeFrom.GetTypeOfColumnAtIndex(i);
//each property has to have a field to store its value in
FieldBuilder backingField = customTypeBuilder.DefineField(propertyName + "_field", propertyType, FieldAttributes.Private);
//body of a property getter
MethodBuilder getMethod = customTypeBuilder.DefineMethod(propertyName + "_get", MethodAttributes.Public | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIlGenerator = getMethod.GetILGenerator();
getIlGenerator.Emit(OpCodes.Ldarg_0);
getIlGenerator.Emit(OpCodes.Ldfld, backingField);
getIlGenerator.Emit(OpCodes.Ret);
///body of a property setter
MethodBuilder setMethod = customTypeBuilder.DefineMethod(propertyName + "_set", MethodAttributes.Public | MethodAttributes.HideBySig, null, new Type[] { propertyType });
ILGenerator setIlGenerator = setMethod.GetILGenerator();
setIlGenerator.Emit(OpCodes.Ldarg_0);
setIlGenerator.Emit(OpCodes.Ldarg_1);
setIlGenerator.Emit(OpCodes.Stfld, backingField);
setIlGenerator.Emit(OpCodes.Ret);
PropertyBuilder customProperty = customTypeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, Type.EmptyTypes);
customProperty.SetGetMethod(getMethod);
customProperty.SetSetMethod(setMethod);
//save all primary key columns to avoid iterating over columns all over again
if (tableToBuildTypeFrom.Columns[i].IsPrimaryKey)
{
primaryKeyFields.Add(backingField);
}
}
customTypeBuilder.AddInterfaceImplementation(typeof(ISelectable));
MethodBuilder getPrimaryKeysMethod = customTypeBuilder.DefineMethod("GetPrimaryKeysValues", MethodAttributes.Public | MethodAttributes.Virtual, typeof(object[]), null);
ILGenerator getPrimaryKeysMethodIlGenerator = getPrimaryKeysMethod.GetILGenerator();
getPrimaryKeysMethodIlGenerator.DeclareLocal(typeof(object[]));
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ldc_I4, primaryKeyFields.Count);
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Newarr, typeof(object));
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Stloc_0);
for (int i = 0; i < primaryKeyFields.Count; i++)
{
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ldloc_0);
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ldc_I4, i);
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ldarg_0);
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ldfld, primaryKeyFields[i]);
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Stelem_Ref);
}
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ldloc_0);
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Ret);
MethodInfo s = typeof(ISelectable).GetMethod("GetPrimaryKeysValues");
customTypeBuilder.DefineMethodOverride(getPrimaryKeysMethod, s);
return customTypeBuilder.CreateType();
}
Способ, которым должен генерироваться метод, взят из MSDN .
Теперь проблема в том, что каждый раз, когда я пытаюсь вызвать метод GetPrimaryKeysValues, VerificationException с сообщением «Операция может дестабилизировать среду выполнения».брошенЯ понятия не имею, что вызывает это.Может ли кто-нибудь помочь?
Спасибо!