Deep C# - Custom Attributes In C#
Written by Mike James   
Friday, 19 March 2021
Article Index
Deep C# - Custom Attributes In C#
Attribute Semantics
Practical Attributes
Using Attributes
An Example
Conclusion

The role of custom attributes in C# can be confusing. They are easy to use when supplied, but how do you go about creating custom attributes? And when are they useful? 

This is  a Chapter of our ebook on C# - a work in progress.

Deep C#

 front

 Chapter List

  1. Value And Reference
  2. Dynamic C#
  3. Passing Parameters
  4. Inheritance 
  5. Casting – the escape from strong typing
  6. Controlling Inheritance
  7. Delegates
  8. Multicast delegates and events
  9. Anonymous Methods, Lambdas And Closures
  10. Take Exception To Everything
  11. What's The Matter With Pointers?
  12. Generics
  13. Structs
  14. The LINQ Principle
  15. XML in C#
  16. Linq and XML
  17. Regular Expressions in depth
  18. Bit Manipulation
  19. Async, Await and the UI problem
  20. The Invoke pattern
  21. The Parallel For
  22. Deep C# - Custom Attributes In C#  ***NEW
  23. Not so complex numbers in C#
  24. Getting Started With .NET IL
Multicast delegates and events
Tuesday, 25 May 2010
Article Index
Multicast delegates and events
Events
Generic Events

Multicast delegates are useful in their own right but they also form the basis on which the C# event system is built. We take a close look at how they work and how to use them. For example, did you know you could add and subtract delegates?

 

Attributes - they really don't seem to be necessary as part of a programming language. After all why "decorate" code with attributes when you can achieve the same results by more direct routes?

In nearly all cases an attribute is an excuse for not implementing a property that does the same job.

However attributes provide a useful extension to the standard language syntax and a way of adding features after the event and without having to extensively re-work the classes that that attributes are applied to.

In other words, the classes that you apply attributes to don't necessarily need to know anything about the attributes you apply.  In this sense attributes have been likened to "code patching" brought up-to-date.

You can use an attribute to add a behaviour without modifying the core code and you can take this behavior away just as easily.

C# has supported and usefully employed attributes for some time but there is still a great deal of confusion about when custom attributes might or might not be useful.

Runtime Metadata

In .NET an attribute is an item of data associated with a programming construct that is stored in the assembly and which can be accessed by the use of reflection.

Notice that some confusion is caused by the fact that some built-in attributes also additionally affect the way that the compiler seems to work. In the main this is not something that most attributes, and certainly not custom attributes, do.

Essentially a custom attribute is a "code comment" that gets compiled into your code, as metadata, and which other code, including you own, can retrieve and possibly act on.

This is the standard explanation of an attribute but the attribute mechanism is so much more.

  • When you retrieve an attribute an instance of a class that represents the attribute is created.

Understanding how this mechanism works means that you can think about exactly how attributes might be useful and how things can go wrong.

There is a sense in which an attribute can always be replaced by a property. For example, you might mark a class as using ASCII encoding for its text and hence implement an [ASCII] attribute. Any other class that make use of a class so marked would have to inspect it to discover that it was ASCII and then arrange to treat it correctly.

It should be fairly obvious that an alternative is to use an ASCII property set to True or False to indicate the same information. Notice that the two approaches have some similarities and some differences:

    • Any client that uses the class has to implement retrieving and testing the attribute or the property and act accordingly – that is, nothing is enforced in either approach.
      • A property can be set at compile time and can be changed at run time. An attribute on the other hand is set at compile time and generally isn’t changed at runtime.
        • A property is associated with instances of a class but an attribute can be associated with many different entities including classes, methods, parameters and so on.

          So:

          • Attributes don’t change and can be associated with a range of entities

          This seems to sum up the situation but notice that with such a flexible implementation you can always change the way things work. This is the standard and most appropriate way of working with attributes.

          csharp

          Implementing A Custom Attribute

          Implementing a custom attribute such as [ASCII], mentioned in the previous section, is fairly easy as long as you don’t read into it more than there is.

          All you have to do is create a class that inherits from Attribute:

          public class ASCIIattribute : Attribute
          {
          }

          It is usual to use a name of the form Xattribute and if you do the system will treat the names X and Xattribute as the same.

          Unfortunately if you do declare the class as Xattribute, e.g. ASCIIattribute, then IntelliSense prompts with the full name. Personally I’d rather keep attribute names short and meaningful so I prefer:

          public class ASCII : Attribute
          {
          }

          Now you can apply the attribute to any class as in:

          [ASCII]
          public class MyClass
          {
          }

          Of course nothing happens if you do this, there is no default attribute behaviour worth worrying about, but it is legal syntax – now to give it some semantics.



          Last Updated ( Friday, 19 March 2021 )