是否可以在运行时添加属性或在运行时更改属性的值?

有帮助吗?

解决方案

属性是静态元数据。程序集,模块,类型,成员,参数和返回值不是C#中的第一类对象(例如, System.Type 类仅仅是类型的反映表示)。您可以获取类型的属性实例,如果属性可写,则更改属性,但在应用于类型时不会影响属性。

其他提示

这实际上取决于你想要完成的目标。

System.ComponentModel.TypeDescriptor 的内容可以用于向类型,属性和对象实例添加属性,并且它具有必须使用它来检索这些属性的限制。如果您正在编写消耗这些属性的代码,并且您可以在这些限制内生存,那么我肯定会建议它。

据我所知,PropertyGrid控件和visual studio设计界面是BCL中唯一使用TypeDescriptor的东西。事实上,这就是他们如何处理他们真正需要做的事情的一半。

你做不到。一种解决方法可能是在运行时生成派生类并添加属性,尽管这可能有点过分。

嗯,只是为了与众不同,我发现了一篇使用Reflection.Emit引用的文章。

以下是链接: http://www.codeproject.com/KB/cs/ dotnetattributes.aspx ,您还需要查看本文底部的一些注释,因为讨论了可能的方法。

不,不是。

属性是元数据,并以二进制形式存储在已编译的程序集中(这也是为什么你只能在其中使用简单类型)。

我不相信。即使我错了,你最希望的是将它们添加到整个类型,而不是类型的实例

如果您需要能够动态添加的内容,则不会使用c#属性。考虑将数据存储在xml中。我最近做了一个项目,我开始w /属性,但最终转移到序列化w / xml。

为什么需要?属性为反射提供了额外的信息,但如果您从外部知道您想要哪些属性,则不需要它们。

您可以相对轻松地在外部将元数据存储在数据库或资源文件中。

我非常努力地使用System.ComponentModel.TypeDescriptor而没有成功。这并不意味着它无法工作,但我希望看到代码。

在对应部分,我想要更改一些属性值。 我做了2个功能,可以正常工作。

        // ************************************************************************
        public static void SetObjectPropertyDescription(this Type typeOfObject, string propertyName,  string description)
        {
            PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
            var att = pd.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
            if (att != null)
            {
                var fieldDescription = att.GetType().GetField("description", BindingFlags.NonPublic | BindingFlags.Instance);
                if (fieldDescription != null)
                {
                    fieldDescription.SetValue(att, description);
                }
            }
        }

        // ************************************************************************
        public static void SetPropertyAttributReadOnly(this Type typeOfObject, string propertyName, bool isReadOnly)
        {
            PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
            var att = pd.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
            if (att != null)
            {
                var fieldDescription = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
                if (fieldDescription != null)
                {
                    fieldDescription.SetValue(att, isReadOnly);
                }
            }
        }

在Java中,我曾经通过使用地图并实现我自己的键值编码来解决这个问题。

http://developer.apple.com/documentation/Cocoa /Conceptual/KeyValueCoding/KeyValueCoding.html

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top