如何属性在运行时添加一个属性 [英] How to add an attribute to a property at runtime

查看:105
本文介绍了如何属性在运行时添加一个属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  //获取给定属性名称的PropertyDescriptor对象
VAR propDesc​​ = TypeDescriptor.GetProperties(typeof运算(T))作为propName];//获取FillAttributes MethodInfo的委托
VAR MethodInfo的= propDesc​​.GetType()的getMethods(BindingFlags.Instance |。BindingFlags.Public |
                                                      BindingFlags.NonPublic可)
    .FirstOrDefault(M = GT; m.IsFamily || m.IsPublic&放大器;&安培; m.Name ==FillAttributes);//创建验证属性
var属性= RequiredAttribute标签新();
VAR属性=新ValidationAttribute [] {}属性;//调用FillAttribute方法
methodInfo.Invoke(propDesc​​,新的对象[] {属性});

你好我试图使用上述code在运行时添加验证属性。但是我收到以下异常:


  

收藏是一个固定大小的



解决方案

不要让别人告诉你,你不能这样做。如果你愿意,你可以为president运行: - )

有关您的conveniance,这是一个完全工作的例子。

 公共类SomeAttribute:属性
    {
        公共SomeAttribute(字符串值)
        {
            THIS.VALUE =价值;
        }        公共字符串值{获得;组; }
    }    公共类SomeClass的
    {
        公共字符串值=测试;
    }    [测试方法]
    公共无效CanAddAttribute()
    {
        VAR类型= ty​​peof运算(SomeClass的);        VAR aName =新System.Reflection.AssemblyName(SomeNamespace);
        VAR AB = AppDomain.CurrentDomain.DefineDynamicAssembly(aName,AssemblyBuilderAccess.Run);
        VAR MB = ab.DefineDynamicModule(aName.Name);
        VAR TB = mb.DefineType(type.Name +代理,System.Reflection.TypeAttributes.Public,类型);        VAR attrCtorParams =新类型[] {typeof运算(字符串)};
        VAR attrCtorInfo = typeof运算(SomeAttribute).GetConstructor(attrCtorParams);
        VAR attrBuilder =新CustomAttributeBuilder(attrCtorInfo,新的对象[] {一些价值});
        tb.SetCustomAttribute(attrBuilder);        VAR NEWTYPE = tb.CreateType();
        VAR例如=(SomeClass的)Activator.CreateInstance(NEWTYPE);        Assert.AreEqual(测试,instance.Value);
        。VAR ATTR =(SomeAttribute)instance.GetType()GetCustomAttributes(typeof运算(SomeAttribute),FALSE).SingleOrDefault();
        Assert.IsNotNull(attr)使用;
        Assert.AreEqual(attr.Value,一些价值);    }

//Get PropertyDescriptor object for the given property name
var propDesc = TypeDescriptor.GetProperties(typeof(T))[propName];

//Get FillAttributes methodinfo delegate
var methodInfo = propDesc.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public |
                                                      BindingFlags.NonPublic)
    .FirstOrDefault(m => m.IsFamily || m.IsPublic && m.Name == "FillAttributes");

//Create Validation attribute
var attribute = new RequiredAttribute();
var  attributes= new ValidationAttribute[]{attribute};

//Invoke FillAttribute method
methodInfo.Invoke(propDesc, new object[] { attributes });

Hi I am trying to add Validation attribute at runtime using the above code. However I am getting the below exception:

Collection was of a fixed size

解决方案

Don't let someone tell you, you can't do it. You can run for president if you want :-)

For your conveniance, this is a fully working example

    public class SomeAttribute : Attribute
    {
        public SomeAttribute(string value)
        {
            this.Value = value;
        }

        public string Value { get; set; }
    }

    public class SomeClass
    {
        public string Value = "Test";
    }

    [TestMethod]
    public void CanAddAttribute()
    {
        var type = typeof(SomeClass);

        var aName = new System.Reflection.AssemblyName("SomeNamespace");
        var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
        var mb = ab.DefineDynamicModule(aName.Name);
        var tb = mb.DefineType(type.Name + "Proxy",System.Reflection.TypeAttributes.Public, type);

        var attrCtorParams = new Type[] { typeof(string) };
        var attrCtorInfo = typeof(SomeAttribute).GetConstructor(attrCtorParams);
        var attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { "Some Value" });
        tb.SetCustomAttribute(attrBuilder);

        var newType = tb.CreateType();
        var instance = (SomeClass)Activator.CreateInstance(newType);

        Assert.AreEqual("Test", instance.Value);
        var attr = (SomeAttribute)instance.GetType().GetCustomAttributes(typeof(SomeAttribute), false).SingleOrDefault();
        Assert.IsNotNull(attr);
        Assert.AreEqual(attr.Value, "Some Value");

    }

这篇关于如何属性在运行时添加一个属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆