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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/129285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:51:35  来源:igfitidea点击:

Can attributes be added dynamically in C#?

提问by Jon Turner

Is it possible to add attributes at runtime or to change the value of an attribute at runtime?

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

采纳答案by Mark Cidade

Attributes are static metadata. Assemblies, modules, types, members, parameters, and return values aren't first-class objects in C# (e.g., the System.Typeclass is merely a reflected representation of a type). You can get an instance of an attribute for a type and change the properties if they're writable but that won't affect the attribute as it is applied to the type.

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

回答by Joel Coehoorn

I don't believe so. Even if I'm wrong, the best you can hope for is adding them to an entire Type, never an instanceof a Type.

我不相信。即使我错了,您所能希望的最好的方法是将它们添加到整个 Type,而不是 Type 的实例

回答by Thomas Danecker

No, it's not.

不,这不对。

Attributes are meta-data and stored in binary-form in the compiled assembly (that's also why you can only use simple types in them).

属性是元数据并以二进制形式存储在编译后的程序集中(这也是您只能在其中使用简单类型的原因)。

回答by petr k.

You can't. One workaround might be to generate a derived class at runtime and adding the attribute, although this is probably bit of an overkill.

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

回答by Darren Kopp

If you need something to be able to added dynamically, c# attributes aren't the way. Look into storing the data in xml. I recently did a project that i started w/ attributes, but eventually moved to serialization w/ xml.

如果您需要能够动态添加的东西,c# 属性不是办法。查看将数据存储在 xml 中。我最近做了一个项目,我开始使用属性,但最终转向使用 xml 进行序列化。

回答by Keith

Why do you need to? Attributes give extra information for reflection, but if you externally know which properties you want you don't need them.

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

You could store meta data externally relatively easily in a database or resource file.

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

回答by Alex Lyman

This really depends on what exactly you're trying to accomplish.

这实际上取决于您究竟要完成什么。

The System.ComponentModel.TypeDescriptorstuff can be used to add attributes to types, properties and object instances, and it has the limitation that you have to use it to retrieve those properties as well. If you're writing the code that consumes those attributes, and you can live within those limitations, then I'd definitely suggest it.

System.ComponentModel.TypeDescriptor东西可以用来添加属性类型,属性和对象实例,它有,你必须用它来读取这些属性以及限制。如果您正在编写使用这些属性的代码,并且您可以生活在这些限制内,那么我肯定会建议您这样做。

As far as I know, the PropertyGrid control and the visual studio design surface are the only things in the BCL that consume the TypeDescriptor stuff. In fact, that's how they do about half the things they really need to do.

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

回答by torial

Well, just to be different, I found an article that references using Reflection.Emit to do so.

好吧,只是为了与众不同,我找到了一篇文章,引用了使用 Reflection.Emit 来做到这一点。

Here's the link: http://www.codeproject.com/KB/cs/dotnetattributes.aspx, you will also want to look into some of the comments at the bottom of the article, because possible approaches are discussed.

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

回答by Daniel Honig

In Java I used to work around this by using a map and implementing my own take on Key-Value coding.

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

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

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

回答by Eric Ouellet

I tried very hard with System.ComponentModel.TypeDescriptor without success. That does not means it can't work but I would like to see code for that.

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

In counter part, I wanted to change some Attribute values. I did 2 functions which work fine for that purpose.

相反,我想更改一些属性值。我做了 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);
                }
            }
        }