Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以在C#中动态添加属性吗?_C#_.net_Attributes - Fatal编程技术网

可以在C#中动态添加属性吗?

可以在C#中动态添加属性吗?,c#,.net,attributes,C#,.net,Attributes,是否可以在运行时添加属性或在运行时更改属性的值?我不这么认为。即使我错了,您也只能希望将它们添加到整个类型中,而不是类型的实例。不,不是 属性是元数据,以二进制形式存储在已编译的程序集中(这也是为什么只能在其中使用简单类型)。不能。一种解决方法可能是在运行时生成派生类并添加属性,尽管这可能有点过分。属性是静态元数据。程序集、模块、类型、成员、参数和返回值不是C#中的第一类对象(例如,System.Type类仅仅是类型的反映表示)。您可以获取类型的属性实例并更改属性(如果属性是可写的),但这不会影

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

我不这么认为。即使我错了,您也只能希望将它们添加到整个类型中,而不是类型的实例。

不,不是


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

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

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

如果您需要能够动态添加的内容,则c#属性不是最佳选择。研究用xml存储数据。我最近做了一个项目,开始时使用了w/attributes,但最终转向了使用xml进行序列化。

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


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

这实际上取决于您要完成的具体任务

这些东西可以用于向类型、属性和对象实例添加属性,并且它有一个限制,即您必须使用它来检索这些属性。如果您正在编写使用这些属性的代码,并且您可以在这些限制范围内生活,那么我绝对建议您这样做


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

好吧,只是不同,我发现了一篇文章引用了使用Reflection.Emit来做这件事


这里是链接:,您还需要查看文章底部的一些注释,因为这里讨论了可能的方法。

在Java中,我曾经通过使用映射和实现我自己的键值编码来解决这个问题


我非常努力地使用System.ComponentModel.TypeDescriptor,但没有成功。这并不意味着它不能工作,但我想看看代码

在计数器部分,我想更改一些属性值。 我做了两个功能,这两个功能为此目的工作得很好

        // ************************************************************************
        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);
                }
            }
        }

请注意,您可以在运行时使用Reflection.Emit类创建属性,但您可以将它们绑定到使用Emit包生成的类,而不是现有的类。这是一个多么无用的答案=))我们都关心现有的类,而不是动态类。@happed,您可以将
YourClass
子类化为
YourRuntimeClassWithAttributes
@mote不确定您的意思,我的类都是预先定义的,这意味着所有基类(我的类继承的)也应该事先定义/确定。我想不出任何方法让它参与到使用Reflection.Emit动态创建的东西中。@如果您想将属性动态添加到现有类
YourClass
,那就没有希望了,您可以在运行时对其进行子类化,并生成一个名称稍有不同的相同类,该类还具有所需的动态创建属性,多态性将允许类型检查代码仍然标识您的baseclass.TypeDescriptor.AddAttributes(Object,Attribute[])向目标组件实例添加类级属性。实际上,大多数数据绑定使用
TypeDescriptor
——而不仅仅是
PropertyGrid
。在Silverlight项目中添加属性元数据属性的任何解决方法(其中未实现
TypeDescriptor
TypeDescriptionProvider
?需要注意的是,TypeDescriptor.GetAttributes()不处理重复的属性。它只选择属性类型的最后一个。例如
[Attr(1)、Attr(2)、Attr(3)]
Attr(3)
已找到。样板消除。如果您可以让一个类根据类中的代码自动生成属性,这不是很方便吗?我正试图找出类似的方法来减少SQL CLR对象中的样板。在其他语言中很容易…请查看链接已断开,请删除您的答案可能不是b这是一种很好的方式,但这是许多其他库选择使用的方式,为了定制这些库的行为,我们需要使用反射(reflection=))真的是一种僵局。这是否回答了您的问题?