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#

 Buy Now From Amazon

DeepCsharp360

 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
       Extract 
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
       Extract
    Structs & Classes 
  6. Inheritance
      
    Extract
    Inheritance
  7. Interfaces & Multiple Inheritance
      
    Extract Interface
  8. Controlling Inheritance
    II Casting & Generics
  9. Casting - The Escape From Strong Typing
      
    Extract Casting I ***NEW!
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic
    Typing
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures
    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For
    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions
    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material

 <ASIN:1871962714>

 <ASIN:B09FTLPTP9>

 

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 )