我正在创建一个动态dll来保存从我的数据库创建的自定义对象。我可以按照我想要的方式创建字段,但是我不明白如何调用构造函数。对于最终生成的结果,我想要:
public class Countries
{
public Countries() { }
public static readonly ReferenceObject USA = new ReferenceObject(120);
public static readonly ReferenceObject CAN = new ReferenceObject(13);
public static readonly ReferenceObject MEX = new ReferenceObject(65);
... //These would be populated from the database
}
我得到的是
public class Countries
{
public Countries() { }
public static readonly ReferenceObject USA;
public static readonly ReferenceObject CAN;
public static readonly ReferenceObject MEX;
...
}
如何将值设置为新的初始化对象?
AppDomain domain = AppDomain.CurrentDomain;
AssemblyName aName = new AssemblyName("DynamicEnums");
AssemblyBuilder ab = domain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
foreach(ReferenceType rt in GetTypes())
{
TypeBuilder tb = mb.DefineType(rt.Name, TypeAttributes.Public);
foreach (Reference r in GetReferences(rt.ID))
{
string name = NameFix(r.Name);
FieldBuilder fb = tb.DefineField(name, typeof(ReferenceObject), FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.Literal);
//Call constructor here... how???
}
types.Add(tb.CreateType());
}
ab.Save(aName.Name + ".dll");
答案 0 :(得分:4)
从我answer到你的另一个(非常相似)问题的副本面食,但是:
AppDomain domain = AppDomain.CurrentDomain;
AssemblyName aName = new AssemblyName("DynamicEnums");
AssemblyBuilder ab = domain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
// Store a handle to the ReferenceObject(int32 pValue)
// constructor.
ConstructorInfo referenceObjectConstructor = typeof(ReferenceObject).GetConstructor(new[] { typeof(int) });
foreach (ReferenceType rt in GetTypes())
{
TypeBuilder tb = mb.DefineType(rt.Name, TypeAttributes.Public);
// Define a static constructor to populate the ReferenceObject
// fields.
ConstructorBuilder staticConstructorBuilder = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
ILGenerator staticConstructorILGenerator = staticConstructorBuilder.GetILGenerator();
foreach (Reference r in GetReferences(rt.ID))
{
string name = r.Abbreviation.Trim();
// Create a public, static, readonly field to store the
// named ReferenceObject.
FieldBuilder referenceObjectField = tb.DefineField(name, typeof(ReferenceObject), FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.InitOnly);
// Add code to the static constructor to populate the
// ReferenceObject field:
// Load the ReferenceObject's ID value onto the stack as a
// literal 4-byte integer (Int32).
staticConstructorILGenerator.Emit(OpCodes.Ldc_I4, r.ID);
// Create a reference to a new ReferenceObject on the stack
// by calling the ReferenceObject(int32 pValue) reference
// we created earlier.
staticConstructorILGenerator.Emit(OpCodes.Newobj, referenceObjectConstructor);
// Store the ReferenceObject reference to the static
// ReferenceObject field.
staticConstructorILGenerator.Emit(OpCodes.Stsfld, referenceObjectField);
}
// Finish the static constructor.
staticConstructorILGenerator.Emit(OpCodes.Ret);
tb.CreateType();
}
ab.Save(aName.Name + ".dll");
答案 1 :(得分:1)
当编写C#类,其中字段初始化时,如示例所示,编译器所做的是在构造函数中生成初始化代码。
我认为你应该这样做:使用TypeBuilder.DefineConstructor
生成构造函数,并在里面创建代码来设置字段。