RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Get Personal with C# Custom Attributes : Page 5

C# attributes may seem like an insignificant element of C# grammar, but did you know they provide a powerful way to extend your metadata? This goes a long way towards simplifying component-based programming. Here's what you need to know about custom attributesand how to use them.

Extensible C#
eXtensible C# (XC#) brings the idea of extensibility to a new level. XC# is both fully compatible with C# and extensible. In addition to all C# language features, XC# also supports arbitrary custom compile time attributes. This means that XC# allows you to go beyond the limited set of compile time attributes supported by C#. XC# comes with compile time attributes for obfuscation, code coverage, declarative assertions, and code verification at the same time that it understands your own compile time attribute. The rest of this article will focus on one of the XC# applications: declarative assertion attributes.

Imperative and Declarative Assertions
Remember imperative and declarative security? The same concept can be applied to assertions. In a nutshell, assertions are Boolean expressions that should always be true. They are incredibly useful in specifying and debugging code.

However, one common mistake is to confuse assertions with exceptions. Exceptions model an abnormal termination, which can occur in correct code and be caught. On the other hand, assertions should never arise; an assertion violation indicates a bug.

Class Debug in the System.Diagnostics namespace provides many variants of the Assert method. Suppose I want to write the hash code of some parameter:

void WriteHashCode (object o)
	Debug.Assert(o != null);
Note that I Assert that o is not null before getting the hash code. Without the call to Assert, passing null to WriteHashCode would result in a NullReferenceException.

XC# goes further by supporting declarative assertions:

[Requires ("o != null")]
void WriteHashCode2 (object o)
In this case, the XC# compiler adds a call to Assert at the beginning of the method. Because this technique can be fairly verbose, XC# comes with a short form for widespread assertions.

void WriteHashCode3 ([NotNull] object o)
Notice that in this case, the assertion applies to the parameter itself.

Besides being easier to write than imperative assertions, declarative assertions have two benefits.

First, declarative assertions are part of the metadata. A client could enumerate the assertions of a given method and do something interesting with them.

Second, declarative assertions are inherited. Suppose for example that the WriteHashCode method implements an interface method. In this case, it is more judicious to declare the assertion at the interface level.

interface IHashCodeWriter
	void WriteHashCode ([NotNull] object o);
Because the interface method does not have any code, no call to Assert is generated at this point. However, the implementer does not need to declare the assertion, the compiler will do it automatically.

class ConsoleHashCodeWriter: IHashCodeWriter
	public void WriteHashCode (object o)
		// Call to Debug.Assert automatically generated here
Flexibility and Extensibility
Custom attributes provide a powerful way to communicate something about your component. Custom attributes can be user attributes, runtime attributes, or compile time attributes depending on the element of the system they interact with. The main point about attributes is extensibility. Not only can you apply attributes to your code but you can also define your own attribute with your own specific semantic. For example, some use attributes to specify tests. In fact, the limit is your imagination.

Pierre Nallet is an independent consultant in the Bay Area specializing in .NET. He is a DevelopMentor instructor and the creator of the XC# compiler. Author of "OLE DB Consumer Templates, A Programmer's Guide" published by Addison Wesley, Pierre graduated from Ecole Polytechnique and Ecole des ponts in Paris, France. Reach him at pierrenallet@resolvecorp.com.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date