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