Free mag vol1 | Page 464

CHAPTER 11  ADVANCED C# LANGUAGE FEATURES myTable.Columns.Add(new DataColumn("Age")); // Now add a row to the table. myTable.Rows.Add("Mel", "Appleby", 60); } // Use multidimension indexer to get details of first row. Console.WriteLine("First Name: {0}", myTable.Rows[0][0]); Console.WriteLine("Last Name: {0}", myTable.Rows[0][1]); Console.WriteLine("Age : {0}", myTable.Rows[0][2]); Do be aware that we’ll take a rather deep dive into ADO.NET beginning with Chapter 21, so if some of the previous code seems unfamiliar, fear not. The main point of this example is that indexer methods can support multiple dimensions, and if used correctly, can simplify the way you interact with contained subobjects in custom collections. Indexer Definitions on Interface Types Indexers can be defined on a given .NET interface type to allow supporting types to provide a custom implementation. Here is a simple example of an interface that defines a protocol for obtaining string objects using a numerical indexer: public interface IStringContainer { string this[int index] { get; set; } } With this interface definition, any class or structure that implements this interface must now support a read/write indexer that manipulates subitems using a numerical value. Here is a partial implementation of such as class: class SomeClass : IStringContainer { private List myStrings = new List(); } public string this[int index] { get { return myStrings[index]; } set { myStrings.Insert(index, value); } } That wraps up the first major topic of this chapter. Now let’s examine a language feature that lets you build custom classes or structures that respond uniquely to the intrinsic operators of C#. Next, allow me to introduce the concept of operator overloading. Understanding Operator Overloading C#, like any programming language, has a canned set of tokens that are used to perform basic operations on intrinsic types. For example, you know that the + operator can be applied to two integers in order to yield a larger integer: 404