- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要在运行时使用 TypeBuilder 创建一个类型。这种类型应该实现一个特定的接口(interface),以便可以在编译时统一处理这种动态类型的实例。
该接口(interface)应返回一个对象数组,其中填充了该类型中特定字段的值。
应该实现的接口(interface)定义如下:
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();
}
最佳答案
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/
我正在业余时间开发一个交互式编译器,我发现我可以使用 TypeBuilder 定义一个类型,它定义两个具有相同名称的字段(并且该类型显然会发出并运行它的初始化程序,这些静态字段在其中初始化,就好了)。
我在业余时间研究交互式编译器,我发现我可以使用 TypeBuilder 定义一个类型,它定义了两个具有相同名称的字段(并且该类型显然会发出并运行它的初始化器,其中初始化这些静态字段,就好了)。查看我的
我有一个帮助程序类,它使用 TypeBuilder 来构造动态类型。它的用法如下: var tbh = new TypeBuilderHelper("MyType"); tbh.AddProperty
我正在创建一个 WCF Web 服务。 我正在尝试根据从数据库返回的信息创建一个类型,用数据构建一个类型列表,然后将其发回。 但是,我得到了一个 Type 'MyDynamicType' with d
假设我有一个 SpaceShip 类,如下所示: public class SpaceShip { public SpaceShip() { } public SpaceShip(I
我正在尝试基于仅包含公共(public)字段的现有类型创建动态类型。新的动态类型还必须继承自仅具有完全实现方法的不同基类型。 我创建了指定基类型的 TypeBuilder,然后我将公共(public)
我有一些代码使用在生成类型上找到的泛型方法的 MethodInfo。为了避免一些反射(reflection),我让代码使用 ldtoken Method ldtoken Type call GetMe
如何检查 Type 对象是否为 TypeBuilderInstantiation? 基本上,我需要一个脱离 Type 的方法。 如果是 TypeBuilderInstantiation,我需要调用 T
我发出了几个类,其中一些需要在自己的构造函数中构造它们的对等体。不存在无限递归依赖(因此如果 A 构造 B,B 将不会构造 A;这对于嵌套引用也是如此 [A 构造 B 构造 C 意味着 B 和 C 都
请帮我在 DisplayAttribute 中添加我尝试过的属性,但将 consturtor 错误设置为 null var fieldName = string.Format(
尝试将应用程序从 .net 4.5 移植到客户端的 .net 核心。我注意到 CreateType 不再是 TypeBuilder 的一部分。我搜索了多个新的反射库,但没有成功。有谁知道如何移植这个?
我正在用 C# 开发一个库,它使用 System.Reflection.Emit.TypeBuilder 类生成运行时类型,我想生成以下类层次结构: [XmlInclude(typeof(Derive
我需要在运行时使用 TypeBuilder 创建一个类型。这种类型应该实现一个特定的接口(interface),以便可以在编译时统一处理这种动态类型的实例。 该接口(interface)应返回一个对象
我想将在运行时生成的类型(通过 TypeBuilder)传递给泛型类中的泛型方法。我不能将它作为对象传递,因为反射用于查找各种属性。 据我所知,这无法完成,因为泛型是在编译时而不是运行时应用的。 我知
我想使用 TypeBuilder 构建一个与接口(interface)匹配的类型。它的基类型将是对象,因为我没有任何抽象点。 有问题的接口(interface)有一个像这样的属性:: public i
我正在使用 Reflection.Emit 制作一个 .NET 兼容的编译器。问题是,虽然 TypeBuilder 是从 Type 派生的,但它不允许我使用 Type 提供的所有方便的方法。 我真正关
我正在创建一个动态 dll 来保存从我的数据库创建的自定义对象。我可以按照我想要的方式创建字段,但是我不明白如何调用构造函数。对于最终生成的结果,我想要: public class Countries
我想在运行时创建类型并通过 Activator.CreateInstance 实例化它。我正在使用 Refletion.Emit 来执行此操作,当创建和实例化类型的方法在单个线程中运行时,一切正常。然
在开始之前,这是我关于 SO 的第一个问题。因此,可能存在错误或缺少有关该问题的信息。如果我需要更正某些内容,请告诉我。谢谢。 使用 TypeBuilder,我正在构建一个实现包含方法的接口(inte
我是一名优秀的程序员,十分优秀!