At Mindseye we’ve written a content management system, which is really just the net result of writing and improving upon a modular code base for a bunch of different websites in a variety of programming languages (ASP.NET, ASP, ColdFusion, and Java). In this content management system, which we’ve affectionately called ‘Element’, a website is distilled down in various ‘objects’; things like events, newsletters, products, etc. Long story short, each object (in whatever language) is usually represented as a specific type and is represented internally as an XML document. In the .NET/C# version that I’ve been working with lately, a newsletter would look vaguely like this:
public class Newsletter {
private XmlDocument newsletter;
public Newsletter(XmlDocument doc) {
this.newsletter = doc;
}
// other methods left out
}
Putting aside your opinion on this being a good or bad design for a second, I’ve always struggled with how to best make the elements of the encapsulated xml document available to external classes. Right now I have a method:
public string GetProperty(string label) {
// retrieve the appropriate element and return as string
return theValue;
}
and this works pretty well, but it’s lengthy. Another way of doing it would be to make each element of the XmlDocument a public property, but this would require alot of typing and would require that you recompile the class everytime the data structure it represented changed. So tonight, during nerd time (ie: extended time by myself at Barnes and Noble) I read about C# indexers. You’ve probably used an indexer before; for instance the NameValueCollection class contains a public property called Item, which itself is a indexer for a specific entry in the NameValueCollection. Unbeknownst to me before tonight, you can create your own indexers, so instead of having to access an element of an object like this:
string newsletterLabel = newsletterInstance.GetProperty("label");
you could instead use this syntax:
string newsletterLabel = newsletterInstance["label"];
which just feels more natural to me. Implementing the indexer in your class is simple. Using the example ‘Newsletter’ class above:
public class Newsletter {
private XmlDocument newsletter;
public Newsletter(XmlDocument doc) {
this.newsletter = doc;
}
// indexer
public string this [string index] {
get {
// logic to retrieve appropriate element from xmldoc by name
return theValue;
}
}
}
I’m guessing that generally the index will be an integer rather than the string that I have above, nothing much changes if the parameter is integer:
public string this [int index] {
get {
// logic to retrieve appropriate element from xmldoc by index
return theValue;
}
}
Extremely handy stuff to know! Couple more thoughts on the subject:
· Indexers
· Comparison Between Properties and Indexers
· Properties
· Developer.com: Using Indexers