用于创建动态类型,并添加各个 public 属性的定义

using System;

using System.Reflection;

using System.Reflection.Emit;

/// <summary>

/// 用于创建动态类型,并添加各个 public 属性的定义

/// </summary>

public class DynamicTypeBuilder

{

    TypeBuilder tb;

    /// <summary>

    /// 构造函数

    /// </summary>

    /// <param name="typeNm">动态类型的名称</param>

    public DynamicTypeBuilder(string typeNm)

    {

        // Silverlight AssemblyBuilderAccess 没有 RunAndSave

        AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(

            new AssemblyName("TempAssembly"), AssemblyBuilderAccess.Run);

 

        ModuleBuilder mb = ab.DefineDynamicModule("TempModule");

        this.tb = mb.DefineType(typeNm, TypeAttributes.Public);

    }

    /// <summary>

    /// 添加一个public的可读写属性,并且会创建对应的名为 propertyNm + "Field" 的私有字段

    /// </summary>

    /// <param name="propertyNm"></param>

    /// <param name="type"></param>

    public void AppendPublicProperty(string propertyNm, Type type)

    {

        this.AppendPublicProperty(propertyNm, type, true, true);

    }

    /// <summary>

    /// 添加一个public属性,并且会创建对应的名为 propertyNm + "Field" 的私有字段

    /// </summary>

    /// <param name="propertyNm"></param>

    /// <param name="type"></param>

    /// <param name="canGet">是否实现getter</param>

    /// <param name="canSet">是否实现setter</param>

    public void AppendPublicProperty(string propertyNm, Type type, bool canGet, bool canSet)

    {

        FieldBuilder field = this.tb.DefineField(string.Format("{0}Field", propertyNm), type, FieldAttributes.Private);

 

        PropertyBuilder property = tb.DefineProperty(propertyNm, PropertyAttributes.HasDefault, type, null);

 

        MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;

 

        if (canGet)

        {

            MethodBuilder getAccessor = tb.DefineMethod(string.Format("get_{0}", propertyNm), getSetAttr, type, Type.EmptyTypes);

            ILGenerator getIL = getAccessor.GetILGenerator();

            #region 按照 IL 代码的写法

            // 按照 IL 代码的写法,不能运行

            //.method public hidebysig specialname instance int32

            //        get_A() cil managed

            //{

            //  // Code size       12 (0xc)

            //  .maxstack  1

            //  .locals init ([0] int32 CS$1$0000)

            //  IL_0000:  nop

            //  IL_0001:  ldarg.0

            //  IL_0002:  ldfld      int32 WpfApplication2.Person::AField

            //  IL_0007:  stloc.0

            //  IL_0008:  br.s       IL_000a

            //  IL_000a:  ldloc.0

            //  IL_000b:  ret

            //} // end of method Person::get_A

 

            // 按照上面 IL 代码的写法,不能运行 :

            //Label getBrsLabel = getIL.DefineLabel();

            //getIL.Emit(OpCodes.Nop);

            //getIL.Emit(OpCodes.Ldarg_0);

            //getIL.Emit(OpCodes.Ldfld, field);

            //getIL.Emit(OpCodes.Stloc_0);

            //getIL.Emit(OpCodes.Br_S, getBrsLabel);

            //getIL.MarkLabel(getBrsLabel);

            //getIL.Emit(OpCodes.Ldloc_0);

            //getIL.Emit(OpCodes.Ret);

            #endregion

            // For an instance property, argument default is the instance. Load the

            // instance, then load the private field and return, leaving the

            // field value on the stack.

            getIL.Emit(OpCodes.Ldarg_0);

            getIL.Emit(OpCodes.Ldfld, field);

            getIL.Emit(OpCodes.Ret);

            property.SetGetMethod(getAccessor);

        }

 

        if (canSet)

        {

            MethodBuilder setAccessor = tb.DefineMethod(string.Format("set_{0}", propertyNm), getSetAttr, null, new Type[] { type });

            setAccessor.DefineParameter(1, ParameterAttributes.None, "value");

            ILGenerator setIL = setAccessor.GetILGenerator();

            // Load the instance and then the numeric argument, then store the

            // argument in the field.

            setIL.Emit(OpCodes.Ldarg_0);

            setIL.Emit(OpCodes.Ldarg_1);

            setIL.Emit(OpCodes.Stfld, field);

            setIL.Emit(OpCodes.Ret);

            property.SetSetMethod(setAccessor);

        }

    }

    /// <summary>

    /// 在添加完各个 public 属性之后,调用此方法以完成对动态类型的定义并加载之,

    /// 此后通过 Activator.CreateInstance() 便可实例化动态类型

    /// </summary>

    /// <returns></returns>

    public Type CreateDynamicType()

    {

        return this.tb.CreateType();

    }

}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 在 Rational Rose 中,可以通过以下步骤设置类的属性名: 1. 首先选中要设置属性名的类,可以是类图中的类或者浏览器中的类。 2. 在类的属性面板中,可以看到属性列表,点击“+”按钮可以添加新的属性。 3. 在属性编辑框中,输入属性名,并选择属性类型、可见性等设置。 4. 点击保存按钮保存修改后的属性名。 注意:属性名必须符合标识符命名规则,不能包含空格和特殊字符。 ### 回答2: 在Rational Rose中,设置类的属性名是通过以下步骤实现的: 1. 打开Rational Rose软件并创建一个新的类图。 2. 在类图中,找到“类”工具栏中的“属性”工具。点击该工具,即可在类图中创建一个属性。 3. 在属性上双击以编辑其名称,并输入所需的属性名。 4. 若要设置属性的数据类型,可以在属性的旁边的文本框中输入正确的数据类型。 5. 如果要设置属性的可见性(例如public、private或protected),可以使用属性旁边的下拉菜单进行选择。 6. 根据需要,可以为属性设置其他属性,例如继承性、静态性等。这些属性可以通过右键单击属性并选择“属性定义”的选项来编辑。 7. 通过重复上述步骤,可以为类添加更多的属性。 请注意,Rational Rose还支持其他更高级的属性设置,例如属性的默认值、约束条件等。这些更高级的设置可以通过在属性上右键单击并选择“属性操作”的选项来访问。 总之,通过使用Rational Rose的类工具栏中的属性工具,可以很容易地在类图中设置属性的名称和其他属性。 ### 回答3: 在Rational Rose中设置类的属性名非常简单。首先,选择你要设置属性的类,然后在Rational Rose的工具栏中找到"属性"按钮,点击它。接着,在弹出的属性面板中,你可以看到一个属性列表,其中包含了类的所有属性。 在属性列表中,你可以添加、删除、修改各个属性的名称。如果你想添加一个新的属性名称,点击列表的底部的"+"按钮,然后输入属性的名称。如果你想删除一个属性名称,选中要删除的属性,在属性名称旁边的"X"按钮上点击。如果你想修改属性的名称,选中要修改的属性,在属性名称旁边的编辑框中输入新的名称。 此外,在属性列表中,你可以为每个属性指定其类型、可见性、默认值等其他属性。这些属性用于更好地定义和描述类的属性。 最后,在你设置完所有属性名称的时候,别忘了点击Rational Rose工具栏的"保存"按钮,以确保你的更改被保存。 总的来说,在Rational Rose中设置类的属性名是一个简单直观的过程,只需要几步操作就可以完成。通过使用属性面板,你可以轻松地添加、删除和修改类的属性的名称和其他相关属性,从而更好地定义和描述你的类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值