如何生成代码,通过调用类的构造函数为静态字段赋值/引用

本文关键字:静态 构造函数 字段 赋值 引用 代码 何生成 调用 | 更新日期: 2023-09-27 17:50:12

(我的代码有点乱c#和VB.NET)我正在尝试发出类,看起来如下:

public class SWTTFields
{
    private string fieldName;
    private int startPosition;
    private int endPosition;
    public static readonly SWTTFields ISO = new SWTTFields("ISO", 1, 2);
    public static readonly SWTTFields EPC = new SWTTFields("EPC", 3, 4);
    private SWTTFields(String fieldName, Int32 startPositon, Int32 endPositon)
    {
        this.fieldName = fieldName;
        this.startPosition = startPositon;
        this.endPosition = endPositon;
    }
}

然而,我在为两个静态成员分配引用时遇到了困难。到目前为止,我得到了这一点(下面的代码是在VB。. NET,但我很乐意接受答案在VB。. NET或c#):

Dim typeBuilder As TypeBuilder = GetTypeBuilder()
'Definition of three private variables
'TODO: you need one more private field that would represent "Bank" particular field belongs to
'Private String fieldName
Dim fieldName As FieldBuilder = typeBuilder.DefineField("fieldName",
                                                         GetType(String),
                                                            FieldAttributes.Private)
'Private Int32 startPosition
Dim startPosition As FieldBuilder = typeBuilder.DefineField("startPosition",
                                                            GetType(Int32),
                                                              FieldAttributes.Private)
'Private Int32 endPosition
Dim endPosition As FieldBuilder = typeBuilder.DefineField("endPosition",
                                                          GetType(Int32), FieldAttributes.Private)
'Type is taken from the current TypeBuilder
Dim ISO As FieldBuilder = typeBuilder.DefineField("ISO", typeBuilder.GetType, FieldAttributes.Public)                                                           
Dim EPC As FieldBuilder = typeBuilder.DefineField("EPC", typeBuilder.GetType, FieldAttributes.Public)
'Constructor parameters are
Dim constructorParams() As Type = {GetType(String), GetType(Int32), GetType(Int32)}
'constructor for the class 
Dim ctorBuilder As ConstructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public Or
                                                                     MethodAttributes.SpecialName Or
                                                                     MethodAttributes.RTSpecialName,
                                                                     CallingConventions.Standard,
                                                                     constructorParams)
Dim objType As Type = Type.GetType("System.Object")
'pulls out info about Object constructor. It will be called later 
Dim objCtor As ConstructorInfo = objType.GetConstructor(Type.EmptyTypes)
'Generating code (some of the code and comments came from ConstructorBuilder class)
Dim ctorIL As ILGenerator = ctorBuilder.GetILGenerator()
'place "this" on the stack 
ctorIL.Emit(OpCodes.Ldarg_0)
'Create instance of System.Object by invokign its ctor
ctorIL.Emit(OpCodes.Call, objCtor)
'store fieldName parameter 
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_1)
ctorIL.Emit(OpCodes.Stfld, fieldName)
'store startPosition
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_2)
ctorIL.Emit(OpCodes.Stfld, startPosition)
'stored endPosition
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_3)
ctorIL.Emit(OpCodes.Stfld, endPosition)
'Done. Return
ctorIL.Emit(OpCodes.Ret)

如何生成代码,通过调用类的构造函数为静态字段赋值/引用

我自己没有使用过TypeBuilder,所以这更多的是一个提示,而不是完整的代码,但基本上我相信你想要TypeBuilder.DefineTypeInitializer,并在那里执行赋值。

换句话说,就其静态成员而言,可以这样考虑类:

public class SWTTFields
{
    public static readonly SWTTFields ISO;
    public static readonly SWTTFields EPC;
    static SWTTFields()
    {
        ISO = new SWTTFields("ISO", 1, 2);
        EPC = new SWTTFields("EPC", 3, 4);
    }
}

(由于静态构造函数的不同,并不完全等同于原始代码,但已经足够接近了)

看起来您已经知道如何为该类型初始化器体生成相关的IL -只需像对待任何其他方法/构造函数体一样对待它。