Introduction to Indexers |
|
A Property Can Be Indexed |
Introduction |
In the previous sections, we learned how to create an array, how to assign values to its elements, and how to get the value of each element. Here is an example: using System; public class Program { static int Main() { double[] Numbers = new double[5]; Numbers[0] = 927.93; Numbers[1] = 45.155; Numbers[2] = 2.37094; Numbers[3] = 73475.25; Numbers[4] = 186.72; for (int i = 0; i < Numbers.Length; i++) Console.WriteLine("Number {0}: {1}", i+1, Numbers[i]); Console.WriteLine(); return 0; } } This would produce: Number 1: 927,93 Number 2: 45,155 Number 3: 2,37094 Number 4: 73475,25 Number 5: 186,72 Press any key to continue . . . |
In the same way, if we declared an array as a member variable of a class, to access the elements of that member, we had to use an instance of the class, followed by the period operator, followed by the member variable applied with the square brackets. Instead of accessing each element through its member variable, you can create a type of property referred to as an indexer.
An indexer, also called an indexed property, is a class's property that allows you to access a member variable of a class using the features of an array. To create an indexed property, start the class like any other. In the body of the class, create a field that is an array. Here is an example: public class Number { double[] Numbers = new double[5]; } Then, in the body of the class, create a property named this with its accessor(s). The this property must be the same type as the field it will refer to. The property must take a parameter as an array. This means that it must have square brackets. Inside of the brackets, include the parameter you will use as index to access the members of the array. Traditionally, and as we have seen so far, you usually access the members of an array using an integer-based index. Therefore, you can use an int type as the index of the array. Of course, the index' parameter must have a name, such as i. This would be done as follows: public class Number { double[] Numbers = new double[5]; public double this[int i] { } } If you want the property to be read-only, include only a get accessor. In the get accessor, you should return an element of the array field the property refers to, using the parameter of the property. This would be done as follows: public class Number { double[] Numbers = new double[5]; public double this[int i] { get { return Numbers[i]; } } } Once you have created the indexed property, the class can be used. To start, you can declare a variable of the class. To access its arrayed field, you can apply the square brackets directly to it. Here is an example: using System; public class Number { double[] Numbers; public double this[int i] { get { return Numbers[i]; } } public Number() { Numbers = new double[5]; Numbers[0] = 927.93; Numbers[1] = 45.155; Numbers[2] = 2.37094; Numbers[3] = 73475.25; Numbers[4] = 186.72; } } public class Program { static int Main() { Number nbr = new Number(); for (int i = 0; i < 5; i++) Console.WriteLine("Number {0}: {1}", i + 1, nbr[i]); Console.WriteLine(); return 0; } } Based on this, a type of formula to create and use a basic indexed property is: class ClassName { DataType[] ArrayName = new DataType[Index]; public DataType this[int i] { get { return ArrayName[i]; } } }
In the above example, we created a property that produced double-precision values. When creating an indexed property, you will decide what type of value the property must produce or the type it can have. As opposed to an int or a double, you can also create a property that takes or produces a string. To do this, you can use the above class template with the desired data type, such as string. Here is an example of a string-based indexed property: using System; public class Philosopher { string[] phil = new string[8]; public string this[int i] { get { return phil[i]; } } public Philosopher() { phil[0] = "Aristotle"; phil[1] = "Emmanuel Kant"; phil[2] = "Tom Huffman"; phil[3] = "Judith Jarvis Thompson"; phil[4] = "Thomas Hobbes"; phil[5] = "Cornell West"; phil[6] = "Jane English"; phil[7] = "James Rachels"; } } public class Program { static int Main() { Philosopher thinker = new Philosopher(); for (int i = 0; i < 8; i++) Console.WriteLine("Philosopher: {0}", thinker[i]); Console.WriteLine(); return 0; } } This would produce: Philosopher: Aristotle Philosopher: Emmanuel Kant Philosopher: Tom Huffman Philosopher: Judith Jarvis Thompson Philosopher: Thomas Hobbes Philosopher: Cornell West Philosopher: Jane English Philosopher: James Rachels Press any key to continue . . . In the same way, you can created a Boolean-based indexed property by simply making it return a bool type. Here is an example: using System; public class DrivingWhileIntoxicated { bool[] dwi = new bool[7]; public bool this[int i] { get { return dwi[i]; } } public DrivingWhileIntoxicated() { dwi[0] = false; dwi[1] = true; dwi[2] = true; dwi[3] = false; dwi[5] = false; dwi[6] = false; } } public class Program { static int Main() { DrivingWhileIntoxicated driving = new DrivingWhileIntoxicated(); Console.WriteLine("Police Report"); Console.WriteLine("-------------------------------"); for(int i = 0; i < 7; i++) Console.WriteLine("Driver Was Intoxicated: {0}", driving[i]); Console.WriteLine(); return 0; } } This would produce: Police Report ------------------------------- Driver Was Intoxicated: False Driver Was Intoxicated: True Driver Was Intoxicated: True Driver Was Intoxicated: False Driver Was Intoxicated: False Driver Was Intoxicated: False Driver Was Intoxicated: False Press any key to continue . . .
In previous lessons, we saw how to create different arrays that are numeric or string based. Here is an example of a float array: using System; public class Program { static int Main() { float[] ages = new float[5]; ages[0] = 14.50f; ages[1] = 12.00f; ages[2] = 16.50f; ages[3] = 14.00f; ages[4] = 15.50f; Console.WriteLine("Student Age: {0}", ages[2]); Console.WriteLine(); return 0; } } When we think of arrays, we usually consider passing an integer-based parameter to the square brackets of the variable, as done for the above ages array: float[] ages = new float[5]; When using an indexed property, you can use almost any type of index, such as a real value or a string. To do this, in the square brackets of the this property, pass the desired type as the index. Here is an example: public class StudentAge { public float this[string name] { } } When defining the indexed property, there are two rules you must follow and you are aware of them already because an indexed property is like a method that takes a parameter and doesn't return void. Therefore, when implementing an indexed property, make sure you return the right type of value and make sure you pass the appropriate index to the return value of the this property. Here is an example: public class StudentAge { public float this[string name] { get { if( name == "Ernestine Jonas" ) return 14.50f; else if( name == "Paul Bertrand Yamaguchi" ) return 12.50f; else if( name == "Helene Jonas" ) return 16.00f; else if( name == "Chrissie Hanson" ) return 14.00f; else if( name == "Bernard Hallo" ) return 15.50f; else return 12.00f; } } } Once you have defined the property, you can use it. To access any of its elements, you must pass the appropriate type of index. In this case, the index must be passed as a string and not an integer. You can then do whatever you want with the value produced by the property. For example, you can display it to the user. Here is an example: using System; public class StudentAge { public float this[string name] { get { if( name == "Ernestine Jonas" ) return 14.50f; else if( name == "Paul Bertrand Yamaguchi" ) return 12.50f; else if( name == "Helene Jonas" ) return 16.00f; else if( name == "Chrissie Hanson" ) return 14.00f; else if( name == "Bernard Hallo" ) return 15.50f; else return 12.00f; } } } public class Program { static int Main() { StudentAge sa = new StudentAge(); float age = sa["Paul Bertrand Yamaguchi"]; Console.WriteLine("Student Name: {0}", age); Console.WriteLine(); return 0; } } This would produce: Student Name: 12.5 Press any key to continue . . . You can also pass an enumeration as an index. To do this, after defining the enumerator, type its name and a parameter name in the square brackets of the this member, then define the property as you see fit. To access the property outside, apply an enumeration member to the square brackets on an instance of the class. Here is an example: using System; public enum CategoryFee { Children, Adult, Senior, Unknown } public class GolfClubMembership { double[] fee = new double[4]; public GolfClubMembership() { fee[0] = 150.95d; fee[1] = 250.75d; fee[2] = 85.65d; fee[3] = 350.00d; } public double this[CategoryFee cat] { get { if (cat == CategoryFee.Children) return fee[0]; else if (cat == CategoryFee.Adult) return fee[1]; else if (cat == CategoryFee.Senior) return fee[2]; else return fee[3]; } } } public class Program { static int Main() { GolfClubMembership mbr= new GolfClubMembership(); Console.WriteLine("Membership Fee: {0}", mbr[CategoryFee.Senior]); Console.WriteLine(); return 0; } } This would produce: Membership Fee: 85.65 Press any key to continue . . .
|
Practical Learning: Creating an Indexer |
using System; namespace PropertyRental1 { public class PropertyListing { public Property[] props; public string this[long code] { get { for(int i = 0; i < props.Length; i++) if( code == props[i].PropertyCode ) return "Property #: " + props[i].PropertyCode + "\nCondition: " + props[i].PropertyCondition + "\nBedrooms: " + props[i].Bedrooms + "\nBathrooms: " + props[i].Bathrooms + "\nMonthly Rent: " + props[i].MonthlyRent.ToString("C"); return "Unidentifiable Property"; } } public PropertyListing() { . . . No Change } } } |
using System; namespace PropertyRental1 { public class Program { static int Main() { PropertyListing properties = new PropertyListing(); long lngCode; Console.WriteLine("Here is a list of our properties by code"); for (int i = 0; i < 6; i++) Console.WriteLine("Property Code: {0}", properties.props[i].PropertyCode); try { Console.Write("Enter Property Code: "); lngCode = long.Parse(Console.ReadLine()); Console.WriteLine("======================================"); Console.WriteLine("Property Information"); Console.WriteLine("--------------------------------------"); Console.WriteLine(properties[lngCode]); Console.WriteLine("======================================"); } catch (FormatException) { Console.WriteLine("=- Invalid Property Code -="); } return 0; } } } |
Here is a list of our properties by code Property Code: 355443 Property Code: 653004 Property Code: 800118 Property Code: 839375 Property Code: 148561 Property Code: 697001 Enter Property Code: 697001 ====================================== Property Information -------------------------------------- Property #: 697001 Condition: Good Bedrooms: 2 Bathrooms: 1 Monthly Rent: $1,050.00 ====================================== Press any key to continue . . . |
|
||
Home | Copyright © 2007-2013, FunctionX | Next |
|