Annotating objects 12 Jun 2007


Two weeks ago, I've borrowed a concept I've first seen in Boo to use it in Cecil.

As the title of this entry kindly suggests, it's about something called annotations. The need for them came from my work on the linker. Before using annotations, to decide which elements to link, I've re-created a tree of objects called markers. For instance, to mark a method, I used to have a class similar to this one:
public class MethodMarker : Marker {

	MethodDefinition method;

}

When it was time to sweep methods in a type, I was checking if the method was found in the markers of a type, and if not, I knew I could safely remove it. That worked well, but I was basically re-creating a parallel object tree to the Cecil one, only to support a few more information.

Here came to me the idea of reusing the annotations concept. Let's have a look at a new interface:
namespace Mono.Cecil {

	using System.Collections;

	public interface IAnnotationProvider {

		IDictionary Annotations { get; }
	}
}

I've ensured that every important type like TypeDefinition or MethodDefinition in Cecil implement this type, et voilĂ , I'm now able to randomly tag them, with whatever data I want.

To keep up with the example of the linker, instead of creating a tree of markers, I now simply annotate a method as «marked», and when it's time to sweep the unused one, the check is now very simple.

Well, that's pretty useful to me, hopefully it will be useful to you too.

UPDATE:

Following the excellent suggestion from Bertrand, I've changed the way the types implement IAnnotationProvider to an explicit implementation, and it looks really better.