【问题标题】:Add Attribute to the property dynamically动态添加属性到属性
【发布时间】:2016-02-23 07:08:00
【问题描述】:

以下动态创建类和属性的实现:

public static class MyTypeBuilder
{
    public static void CreateNewObject()
    {
        var myType = CompileResultType();

    }
    public static Type CompileResultType()
    {
        TypeBuilder tb = GetTypeBuilder();
        ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

                        var fields = new List<Field>() { 
            new Field("EmployeeID", typeof(int)),
            new Field("EmployeeName", typeof(string)),
            new Field("Designation", typeof(string)) 
        };

        // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type)
                        foreach (var field in fields)
            CreateProperty(tb, field.FieldName, field.FieldType);

        Type objectType = tb.CreateType();
        return objectType;
    }

    private static TypeBuilder GetTypeBuilder()
    {
        var typeSignature = "MyDynamicType";
        var an = new AssemblyName(typeSignature);
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
        TypeBuilder tb = moduleBuilder.DefineType(typeSignature
                            , TypeAttributes.Public |
                            TypeAttributes.Class |
                            TypeAttributes.AutoClass |
                            TypeAttributes.AnsiClass |
                            TypeAttributes.BeforeFieldInit |
                            TypeAttributes.AutoLayout
                            , null);
        return tb;
    }

    private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
    {
        FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

        PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
        MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
        ILGenerator getIl = getPropMthdBldr.GetILGenerator();

        getIl.Emit(OpCodes.Ldarg_0);
        getIl.Emit(OpCodes.Ldfld, fieldBuilder);
        getIl.Emit(OpCodes.Ret);

        MethodBuilder setPropMthdBldr =
            tb.DefineMethod("set_" + propertyName,
              MethodAttributes.Public |
              MethodAttributes.SpecialName |
              MethodAttributes.HideBySig,
              null, new[] { propertyType });

        ILGenerator setIl = setPropMthdBldr.GetILGenerator();
        Label modifyProperty = setIl.DefineLabel();
        Label exitSet = setIl.DefineLabel();

        setIl.MarkLabel(modifyProperty);
        setIl.Emit(OpCodes.Ldarg_0);
        setIl.Emit(OpCodes.Ldarg_1);
        setIl.Emit(OpCodes.Stfld, fieldBuilder);

        setIl.Emit(OpCodes.Nop);
        setIl.MarkLabel(exitSet);
        setIl.Emit(OpCodes.Ret);

        propertyBuilder.SetGetMethod(getPropMthdBldr);
        propertyBuilder.SetSetMethod(setPropMthdBldr);
    }
}

在上述相同的实现中,我想为属性添加属性 示例

[DelimitedRecord(",")]
   [IgnoreEmptyLines()]
   private class myDyanmicType
   {   
       [FieldQuoted('"', QuoteMode.OptionalForBoth)]
       public int EmployeeID;     
       [FieldQuoted('"', QuoteMode.OptionalForBoth)]
       public String EmployeeName;
       [FieldQuoted('"', QuoteMode.OptionalForBoth)]
       public String Designation;          

   }

所以我想为属性添加属性,比如

[FieldQuoted('"', QuoteMode.OptionalForBoth)]

我将如何通过创建动态类和属性的代码来实现这一点

请帮忙。

【问题讨论】:

  • 不,除非课程是为此而设计的,否则您不能这样做。 为什么你要这样做?您可以使用引用现有类的实例的不同类吗?没有更多背景信息很难为您提供帮助。
  • 如果否,是否可以使用动态属性和属性的属性动态创建整个类。现在我可以使用上面的代码动态创建类和属性更新了主要问题描述请检查。
  • 是的,您可以动态创建类,或者使用 ExpandoObject... 但这与说“我已经有了一个类,我想添加属性”非常不同动态的。”目前尚不清楚您真正想要达到什么目标,或者为什么您认为以这种方式最好。
  • 已经上课是我尝试的一种方法。如果这不能轻松实现,那么 我将使用上面代码已经实现的动态属性动态创建整个类,但现在只有一件事我无法理解我将如何添加动态属性到我用上面的代码创建的那些属性。
  • 我建议你完全重写这个问题,以便非常清楚你当时想要做什么。目前我还不清楚。

标签: c# dynamicobject


【解决方案1】:

只是一种更简单、更快捷的方法:将您欣赏的代码写成一个字符串,然后在运行时编译它,一切就绪!

string src = "[DelimitedRecord(\",\")] [IgnoreEmptyLines()] private class ...";
var compParms = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory = true
            };
var csProvider = new CSharpCodeProvider();
CompilerResults compilerResults = csProvider.CompileAssemblyFromSource(compParms, src);
var a = compilerResults.CompiledAssembly; // here you go

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    相关资源
    最近更新 更多