gpt4 book ai didi

.NET TypeBuilder - VerificationException : Operation could destabilize the runtime

转载 作者:行者123 更新时间:2023-12-04 06:47:18 32 4
gpt4 key购买 nike

我需要在运行时使用 TypeBuilder 创建一个类型。这种类型应该实现一个特定的接口(interface),以便可以在编译时统一处理这种动态类型的实例。

该接口(interface)应返回一个对象数组,其中填充了该类型中特定字段的值。

应该实现的接口(interface)定义如下:

public interface ISelectable
{
object[] GetPrimaryKeysValues();
}

这是我用来为接口(interface)生成方法的代码:
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。被抛出。我不知道是什么原因造成的。有人可以帮忙吗?

谢谢!

最佳答案

stelem.ref操作码将对象引用存储到数组中。这意味着如果您有值类型的字段(例如 int s),那么您需要确保在将它们存储到数组之前将它们装箱。因此,您应该添加类似

if (primaryKeyFields[i].FieldType.IsValueType) {
getPrimaryKeysMethodIlGenerator.Emit(OpCodes.Box, primaryKeyFields[i].FieldType);
}

紧接在 stelem.ref 之前操作说明。

此外,虽然这不会导致验证异常,但请注意您的属性的方法名称应该是 get_{Name}set_{Name} ,而不是 {Name}_get{Name}_set .

关于.NET TypeBuilder - VerificationException : Operation could destabilize the runtime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3565508/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com