Can attributes be added dynamically in C#?

C#.NetAttributes

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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

The System.ComponentModel.TypeDescriptor stuff 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.

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.

Solution 2 - C#

Attributes are static metadata. Assemblies, modules, types, members, parameters, and return values aren't first-class objects in C# (e.g., the System.Type class 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.

Solution 3 - C#

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.

Solution 4 - C#

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

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.

Solution 5 - C#

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).

Solution 6 - C#

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 instance of a Type.

Solution 7 - C#

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.

Solution 8 - C#

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.

Solution 9 - C#

Like mentionned in a comment below by Deczaloth, I think that metadata is fixed at compile time. I achieve it by creating a dynamic object where I override GetType() or use GetCustomType() and writing my own type. Using this then you could...

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.

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

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

Solution 10 - C#

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJon TurnerView Question on Stackoverflow
Solution 1 - C#Alex LymanView Answer on Stackoverflow
Solution 2 - C#Mark CidadeView Answer on Stackoverflow
Solution 3 - C#petr k.View Answer on Stackoverflow
Solution 4 - C#torialView Answer on Stackoverflow
Solution 5 - C#Thomas DaneckerView Answer on Stackoverflow
Solution 6 - C#Joel CoehoornView Answer on Stackoverflow
Solution 7 - C#Darren KoppView Answer on Stackoverflow
Solution 8 - C#KeithView Answer on Stackoverflow
Solution 9 - C#Eric OuelletView Answer on Stackoverflow
Solution 10 - C#Daniel HonigView Answer on Stackoverflow