在运行时创建时,在类中不存在构造函数中具有数组的自定义属性 [英] Custom Attribute that has array in constructor not present in the class when created in runtime

查看:68
本文介绍了在运行时创建时,在类中不存在构造函数中具有数组的自定义属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个自定义属性-定义了一些我可以在PropertyGrid中使用的值,以建立用户在编辑属性值时可以从中选择的有效值列表,但不仅限于此:

I have this custom attribute - that defines some values I could use in PropertyGrid to build list of valid values that user can pick from when editing property value, but is not limited to this:

/// <summary>
    /// Apply list of valid known values for specific property
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
    sealed class ValidValuesAttribute : Attribute
    {
        readonly string[] _validValues;

        public ValidValuesAttribute(params string[] values)
        {
            this._validValues = values;
        }

        /// <summary>
        /// List of well-known values
        /// </summary>
        public string[] ValidValues
        {
            get { return _validValues; }
        }
    }



当我在设计"时使用它时,它会完美工作:



When I use this in "design" time, it works perfectly:

[DefaultValue("A1")]
[Editor(typeof(DropSelectEditor), typeof(UITypeEditor))] 
[ValidValues(new string[] {"A1", "B2", "C$" })]
public string ConnectedState { get; set; }



当我尝试使用"params"构造函数时,它也很好用.

然后,我将使用CustomAttributeBuilder在运行时中构建此属性.看起来一切正常:



It also worked well when i tried with "params" constructor.

Then I''m building this property in runtime, using CustomAttributeBuilder. All of it looks to work fine:

private CustomAttributeBuilder GetAttributeBuilder_ValidValuesAttribute(PropertyDefinition tProperty)
        {
            string[] values = (string[]) tProperty.PropertyMetadata.AllowedValues.ToArray().Clone();

            if (values.Length > 0)
            {
                Type[] ctorParams = new Type[] { typeof(string[]) };
                ConstructorInfo classCtorInfo = typeof(ValidValuesAttribute).GetConstructor(ctorParams);
                CustomAttributeBuilder builder = new CustomAttributeBuilder(classCtorInfo, new object[] { values });

                return builder;
            }
            else
                return null;
        }



而且当我将其传递给PropertyBuilder时也很好:



and is also fine, when I''m passing it to PropertyBuilder:

builder = GetAttributeBuilder_ValidValuesAttribute(propertyMeta);
if (builder != null)
myPropertyBuilder.SetCustomAttribute(builder);



即使在Debug中,我也可以看到builder中存在数据blob,其中包含我刚刚在构造函数中设置的内容.

(此时有一些其他属性正在添加-EditorAttribute,DefaultValueAttribute等.它们都可以正常工作.)

然后,我只创建这种类型的实例:



Even in Debug, I can see that there is data blob in builder that contains what I''d just set in the constructing function.

(There is list of other attributes that are being added at this time - EditorAttribute, DefaultValueAttribute etc. All of them work just fine.)

Then I just create instance of this type:

object obj = Activator.CreateInstance(t);



但是,当我尝试枚举其中之一的属性时,会发现除此属性之外的所有属性(包括其他自定义属性).像这样:



But when I try to enumerate attributes on one of those dynamic roperties, I find all attributes (including other custom ones) except this one. Like that:

foreach (PropertyInfo propInfo in obj.GetType().GetProperties())
            {
                foreach (object att in propInfo.GetCustomAttributes(false))
                {
                    // There were no droid I've been looking for!
                }
            }



因此,在我重新设计类以从我将附加到对象的metada读取这些数组之前(从设计角度来看这很好,但不是PropertyGrid的一般使用方式),我想知道:

1.我做错了吗?忽略了一些关键的东西吗?
2.还是有错误?
3.或者我可能会使用除那个简单激活剂之外的其他激活剂


简要说明一下-看来,我创建的其他所有东西都很好,类型和对象的创建没有任何错误,其他属性存在并且可以正常工作,并且带有属性的对象已在PropertyGrid中正确呈现.

我一直在寻找这样的代码,但是似乎字符串数组是可以与Attribute一起使用的有效类型.没有找到一个有这样问题的人,也没有一个人尝试这样做.

预先感谢您提供任何线索.
Sebastian



So, before I redesign a bit my classes to read these array from metada that I will attach to the object (It''s fine from design point but not the way the PropertyGrid is intended to be used in general), I would like to know:

1. Did I made any mistake? Ommited something crucial?
2. Or there is just error?
3. Or maybe I shall use other activator than that simple one


Just for a quick note - It seems, that I''d created everything else well, type and object are created without any errors, other attributes exist and work correctly, and objects with properties are being rendered in PropertyGrid properly.

I''ve been looking for some code like this, but it only seems that array of string is a valid type to be used with Attribute. Did not found a person that had such problem, but also no one that tried doing this.

Thank you in advance for any clues.
Sebastian

推荐答案

"})] 公共 字符串 ConnectedState { get ; 设置; }
" })] public string ConnectedState { get; set; }



当我尝试使用"params"构造函数时,它也很好用.

然后,我将使用CustomAttributeBuilder在运行时中构建此属性.看起来一切正常:



It also worked well when i tried with "params" constructor.

Then I''m building this property in runtime, using CustomAttributeBuilder. All of it looks to work fine:

private CustomAttributeBuilder GetAttributeBuilder_ValidValuesAttribute(PropertyDefinition tProperty)
        {
            string[] values = (string[]) tProperty.PropertyMetadata.AllowedValues.ToArray().Clone();

            if (values.Length > 0)
            {
                Type[] ctorParams = new Type[] { typeof(string[]) };
                ConstructorInfo classCtorInfo = typeof(ValidValuesAttribute).GetConstructor(ctorParams);
                CustomAttributeBuilder builder = new CustomAttributeBuilder(classCtorInfo, new object[] { values });

                return builder;
            }
            else
                return null;
        }



而且当我将其传递给PropertyBuilder时也很好:



and is also fine, when I''m passing it to PropertyBuilder:

builder = GetAttributeBuilder_ValidValuesAttribute(propertyMeta);
if (builder != null)
myPropertyBuilder.SetCustomAttribute(builder);



即使在Debug中,我也可以看到builder中存在数据blob,其中包含我刚刚在构造函数中设置的内容.

(目前有一些其他属性正在添加,包括EditorAttribute,DefaultValueAttribute等.它们都可以正常工作.)

然后,我只创建这种类型的实例:



Even in Debug, I can see that there is data blob in builder that contains what I''d just set in the constructing function.

(There is list of other attributes that are being added at this time - EditorAttribute, DefaultValueAttribute etc. All of them work just fine.)

Then I just create instance of this type:

object obj = Activator.CreateInstance(t);



但是,当我尝试枚举其中之一的属性时,会发现除此属性之外的所有属性(包括其他自定义属性).像这样:



But when I try to enumerate attributes on one of those dynamic roperties, I find all attributes (including other custom ones) except this one. Like that:

foreach (PropertyInfo propInfo in obj.GetType().GetProperties())
            {
                foreach (object att in propInfo.GetCustomAttributes(false))
                {
                    // There were no droid I've been looking for!
                }
            }



因此,在我重新设计类以从我将附加到对象的metada读取这些数组之前(从设计角度来看这很好,但不是PropertyGrid的一般使用方式),我想知道:

1.我做错了吗?忽略了一些关键的东西吗?
2.还是有错误?
3.或者我可能会使用除那个简单激活剂之外的其他激活剂


简要说明一下-看来,我创建的其他所有东西都很好,类型和对象的创建没有任何错误,其他属性存在并且可以正常工作,并且带有属性的对象已在PropertyGrid中正确呈现.

我一直在寻找这样的代码,但是似乎字符串数组是可以与Attribute一起使用的有效类型.没有找到一个有这样问题的人,也没有一个人尝试这样做.

预先感谢您提供任何线索.
塞巴斯蒂安



So, before I redesign a bit my classes to read these array from metada that I will attach to the object (It''s fine from design point but not the way the PropertyGrid is intended to be used in general), I would like to know:

1. Did I made any mistake? Ommited something crucial?
2. Or there is just error?
3. Or maybe I shall use other activator than that simple one


Just for a quick note - It seems, that I''d created everything else well, type and object are created without any errors, other attributes exist and work correctly, and objects with properties are being rendered in PropertyGrid properly.

I''ve been looking for some code like this, but it only seems that array of string is a valid type to be used with Attribute. Did not found a person that had such problem, but also no one that tried doing this.

Thank you in advance for any clues.
Sebastian


你好塞巴斯蒂安,

为什么要遍历属性?我得到的印象是,您滥用"属性,因为您可以直接做一些没有属性的事情.也许我错了.

您似乎在运行时加载元数据,因此,请使用填充的通用数据结构并在运行时传递给PropertyGrid-而不是属性.

我对属性的看法是可以在编译时声明并通过 reflection 进行访问.

大概大多数开发人员都是这样看的-难怪您几乎找不到任何人在做您想做的事情.

干杯

安迪
Hello Sebastian,

Why going over attributes? I get the impression that you "abuse" the attribjtes for something you could do straight forward without attributes. Maybe I''m wrong.

You seem to load the meta data at runtime, so, use a common data structure that you populate and pass to your PropertyGrid at runtime - not attributes.

My view of attributes is something for declaring at compile time and accessing via reflection.

Probably most of the developers view it like this - no wonder that you hardly find anyone doing what you''re trying to do.

Cheers

Andi


这篇关于在运行时创建时,在类中不存在构造函数中具有数组的自定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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