{"id":535,"date":"2003-11-06T20:58:13","date_gmt":"2003-11-07T00:58:13","guid":{"rendered":"http:\/\/wordpress.cephas.net\/?p=535"},"modified":"2003-11-06T20:58:13","modified_gmt":"2003-11-07T00:58:13","slug":"c-indexers","status":"publish","type":"post","link":"https:\/\/cephas.net\/blog\/2003\/11\/06\/c-indexers\/","title":{"rendered":"C# Indexers"},"content":{"rendered":"<p>At <a href=\"http:\/\/www.mindseye.com\/\">Mindseye<\/a> we&#8217;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&#8217;ve affectionately called <a href=\"http:\/\/www.mindseyeelement.com\/\">&#8216;Element&#8217;<\/a>, a website is distilled down in various &#8216;objects&#8217;; 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&#8217;ve been working with lately, a newsletter would look vaguely like this:<br \/>\n<code><br \/>\npublic class Newsletter {<br \/>\n&nbsp;&nbsp;private <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/cpref\/html\/frlrfSystemXmlXmlDocumentClassTopic.asp\">XmlDocument<\/a> newsletter;<br \/>\n&nbsp;&nbsp;public Newsletter(XmlDocument doc) {<br \/>\n&nbsp;&nbsp;&nbsp;this.newsletter = doc;<br \/>\n&nbsp;&nbsp;}<br \/>\n&nbsp;&nbsp;\/\/ other methods left out<br \/>\n}<br \/>\n<\/code><br \/>\nPutting aside your opinion on this being a good or bad design for a second, I&#8217;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:<br \/>\n<code><br \/>\npublic string GetProperty(string label) {<br \/>\n&nbsp;&nbsp;\/\/ retrieve the appropriate element and return as string<br \/>\n&nbsp;&nbsp;return theValue;<br \/>\n}<br \/>\n<\/code><br \/>\nand this works pretty well, but it&#8217;s lengthy. Another way of doing it would be to make each element of the XmlDocument a public <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/csref\/html\/vclrfusingproperties.asp\">property<\/a>, 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&#8217;ve probably used an indexer before; for instance the <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/cpref\/html\/frlrfSystemCollectionsSpecializedNameValueCollectionClassTopic.asp\">NameValueCollection<\/a> class contains a public property called <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/cpref\/html\/frlrfsystemcollectionsspecializednamevaluecollectionclassitemtopic.asp?frame=true\">Item<\/a>, 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:<br \/>\n<code><br \/>\nstring newsletterLabel =  newsletterInstance.GetProperty(\"label\");<br \/>\n<\/code><br \/>\nyou could instead use this syntax:<br \/>\n<code><br \/>\nstring newsletterLabel = newsletterInstance[\"label\"];<br \/>\n<\/code><br \/>\nwhich just feels more natural to me.  Implementing the indexer in your class is simple. Using the example &#8216;Newsletter&#8217; class above:<br \/>\n<code><br \/>\npublic class Newsletter {<br \/>\n&nbsp;&nbsp;private XmlDocument newsletter;<br \/>\n&nbsp;&nbsp;public Newsletter(XmlDocument doc) {<br \/>\n&nbsp;&nbsp;&nbsp;this.newsletter = doc;<br \/>\n&nbsp;&nbsp;}<br \/>\n&nbsp;&nbsp;\/\/ indexer<br \/>\n&nbsp;&nbsp;public string this [string index] {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;get {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/ logic to retrieve appropriate element from xmldoc by name<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return theValue;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;}<br \/>\n&nbsp;&nbsp;}<br \/>\n}<br \/>\n<\/code><br \/>\nI&#8217;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:<br \/>\n<code><br \/>\npublic string this [int index] {<br \/>\n&nbsp;&nbsp;get {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;\/\/ logic to retrieve appropriate element from xmldoc by index<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return theValue;<br \/>\n&nbsp;&nbsp;}<br \/>\n}<br \/>\n<\/code><br \/>\nExtremely handy stuff to know! Couple more thoughts on the subject:<\/p>\n<p>&middot; <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/csref\/html\/vcerrusingindexers.asp\">Indexers<\/a><br \/>\n&middot; <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/csref\/html\/vclrfcomparisonbetweenpropertiesindexers.asp\">Comparison Between Properties and Indexers<\/a><br \/>\n&middot; <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/csref\/html\/vclrfUsingProperties.asp?frame=true\">Properties<\/a><br \/>\n&middot; <a href=\"http:\/\/www.developer.com\/net\/csharp\/article.php\/1547581\">Developer.com: Using Indexers<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At Mindseye we&#8217;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&#8217;ve affectionately called &#8216;Element&#8217;, a website is distilled &hellip; <a href=\"https:\/\/cephas.net\/blog\/2003\/11\/06\/c-indexers\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">C# Indexers<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[17],"tags":[],"_links":{"self":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/535"}],"collection":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/comments?post=535"}],"version-history":[{"count":0,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/535\/revisions"}],"wp:attachment":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/media?parent=535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/categories?post=535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/tags?post=535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}