Home

Topics on Indexers and Classes

 

A Class as Index

As opposed to returning a class, an indexer can use a class as its index. When creating such a property, the primary action you must take is to include a class and its name as a parameter to the this property. You can start such a class as follows:

using System;

public enum Classification
{
    Female,
    Male,
    Unknown
}

public class Student
{
    public long StudentID;
    public string FirstName;
    public string LastName;
    public Classification Gender;
}

public class SchoolRegistration
{
    public string this[Student std]
    {
    }
}

When implementing the class, you should proceed the same way we have done so far following the rules of a method that takes an argument and returns a value other than void. Here is an example:

public class SchoolRegistration
{
    Student[] students = new Student[50];

    public string this[Student std]
    {
        get
        {
            for (int i = 0; i < students.Length; i++)
            {
                if (std.StudentID == students[i].StudentID)

                    return "Student ID: " + students[i].StudentID +
                           "\nFirst Name: " + students[i].FirstName +
                           "\nLast Name:  " + students[i].LastName +
                           "\nGender:     " + students[i].Gender;
            }

            // Unknown student or the number was not found
            return "";
        }
    }
}

After creating the property, you can use it. To do this, you must pass an object that is the type of the index. You can then use the returned value as you see fit. Here is an example:

using System;

public enum Classification
{
    Female,
    Male,
    Unknown
}

public class Student
{
    public long StudentID;
    public string FirstName;
    public string LastName;
    public Classification Gender;
}

public class SchoolRegistration
{
    Student[] students = new Student[50];

    public string this[Student std]
    {
        get
        {
            for (int i = 0; i < students.Length; i++)
            {
                if (std.StudentID == students[i].StudentID)

                    return "Student ID: " + students[i].StudentID +
                           "\nFirst Name: " + students[i].FirstName +
                           "\nLast Name:  " + students[i].LastName +
                           "\nGender:     " + students[i].Gender;
            }

            // Unknown student or the number was not found
            return "";
        }
    }

    public SchoolRegistration()
    {
        students[0] = new Student();
        students[0].StudentID = 917294;
        students[0].FirstName = "Helene";
        students[0].LastName = "Mukoko";
        students[0].Gender = Classification.Female;

        students[1] = new Student();
        students[1].StudentID = 283764;
        students[1].FirstName = "Patrice";
        students[1].LastName = "Katts";
        students[1].Gender = Classification.Unknown;

        students[2] = new Student();
        students[2].StudentID = 192046;
        students[2].FirstName = "Armand";
        students[2].LastName = "Essono";
        students[2].Gender = Classification.Male;

        students[3] = new Student();
        students[3].StudentID = 618268;
        students[3].FirstName = "Bertrand";
        students[3].LastName = "Yamaguchi";
        students[3].Gender = Classification.Male;

        students[4] = new Student();
        students[4].StudentID = 820648;
        students[4].FirstName = "Hortense";
        students[4].LastName = "McNeal";
        students[4].Gender = Classification.Female;

        students[5] = new Student();
        students[5].StudentID  = 917394;
        students[5].FirstName = "Alfredo";
        students[5].LastName = "Olmos";
        students[5].Gender = Classification.Unknown;

        students[6] = new Student();
        students[6].StudentID  = 163864;
        students[6].FirstName = "Josiane";
        students[6].LastName = "Euler";
        students[6].Gender = Classification.Female;

        students[7] = new Student();
        students[7].StudentID  = 826384;
        students[7].FirstName = "Joan";
        students[7].LastName = "Jones";
        students[7].Gender =  Classification.Female ;
    }
}

public class Program
{
    static int Main()
    {
        SchoolRegistration pupils = new SchoolRegistration();

        Student pupil = new Student();
        pupil.StudentID = 820648;

        string strStudent = pupils[pupil];
        Console.WriteLine("=====================");
        Console.WriteLine("Student Information");
        Console.WriteLine("---------------------");
        Console.WriteLine(strStudent);

        //pupil = new Student();
        pupil.StudentID = 192046;
        strStudent = pupils[pupil];

        Console.WriteLine("=====================");
        Console.WriteLine("Student Information");
        Console.WriteLine("---------------------");
        Console.WriteLine(strStudent);

        Console.WriteLine("=====================\n");
        return 0;
    }
}

This would produce:

=====================
Student Information
---------------------
Student ID: 820648
First Name: Hortense
Last Name:  McNeal
Gender:     Female
=====================
Student Information
---------------------
Student ID: 192046
First Name: Armand
Last Name:  Essono
Gender:     Male
=====================

Press any key to continue . . .

You can also directly pass an instance of the class in the square brackets of the object that holds the indexed property, as long as you specify the object. Here is an example:

using System;

public enum Classification
{
    Female,
    Male,
    Unknown
}

public class Student
{
    public long StudentID;
    public string FirstName;
    public string LastName;
    public Classification Gender;

    public Student()
    {
    }

    public Student(long id)
    {
        this.StudentID = id;
    }
}

public class SchoolRegistration
{
    Student[] students = new Student[50];

    public string this[Student std]
    {
        . . . No Change
    }

    public SchoolRegistration()
    {
        . . . No Change
    }
}

public class Program
{
    static int Main()
    {
        SchoolRegistration pupils = new SchoolRegistration();

        string strStudent = pupils[new Student(618268)];
        Console.WriteLine("=====================");
        Console.WriteLine("Student Information");
        Console.WriteLine("---------------------");
        Console.WriteLine(strStudent);

        Console.WriteLine("=====================\n");
        return 0;
    }
}

This would produce:

=====================
Student Information
---------------------
Student ID: 618268
First Name: Bertrand
Last Name:  Yamaguchi
Gender:     Male
=====================

Press any key to continue . . .

Overloading a Class-Based Indexed Property

As mentioned for indexers that return primitive types, you can overload an indexed property that produces a class. You do this following the same rules applied to method overloading and arrays:

  • If two indexed properties take only one parameter, each must take a different type of parameter than the other. The parameter can be a primitive type or a class. Here are examples:
     
    using System;
    
    public enum Classification
    {
        Female,
        Male,
        Unknown
    }
    
    public class Major
    {
        public string Name;
        public int CreditsRequired;
    }
    
    public class Student
    {
        public long StudentNumber;
        public string FullName;
        public Classification Gender;
    
        public override string ToString()
        {
            string str = "Student #:     " + StudentNumber.ToString() +
                         "\nFull Name:     " + FullName +
                         "\nGender:        " + Gender;
            return str;
        }
    }
    
    public class StudentRegistration
    {
        private Student[] std = new Student[5];
    
        public StudentRegistration()
        {
            std[0] = new Student();
            std[0].StudentNumber = 304850;
            std[0].FullName = "Helene Mukoko";
            std[0].Gender = Classification.Female;
    
            std[1] = new Student();
            std[1].StudentNumber = 926304;
            std[1].FullName = "Patrice Katts";
            std[1].Gender = Classification.Unknown;
    
            std[2] = new Student();
            std[2].StudentNumber = 330647;
            std[2].FullName = "Armand Essono";
            std[2].Gender = Classification.Male;
    
            std[3] = new Student();
            std[3].StudentNumber = 631846;
            std[3].FullName = "Bertrand Yamaguchi";
            std[3].Gender = Classification.Male;
    
            std[4] = new Student();
            std[4].StudentNumber = 209374;
            std[4].FullName = "Anselme Bongos";
            std[4].Gender = Classification.Male;
        }
    
        // This property takes a string and produces a Student object
        public Student this[string strFullName]
        {
            get
            {
                for (int i = 0; i < std.Length; i++)
                {
                    if (std[i].FullName == strFullName)
                        return std[i];
                }
                return null;
            }
        }
    
        // This property takes a number and produces a Student object
        public Student this[long nbr]
        {
            get
            {
                for (int i = 0; i < std.Length; i++)
                {
                    if( nbr == std[i].StudentNumber )
                        return std[i];
                }
                return null;
            }
        }
    
        // This property takes a major produces its definition
        public string this[Major maj]
        {
            get
            {
                return "Major: " + maj.Name +
                       " - " + maj.CreditsRequired +
                       " Credits Required";
            }
        } 
    }
    
    class Program
    {
        static int Main()
        {
            StudentRegistration pupils = new StudentRegistration();
    
            Major m1 = new Major();
            m1.Name = "Computer Sciences";
            m1.CreditsRequired = 120;
    
            Major m2 = new Major();
            m2.Name = "Informtation Technology";
            m2.CreditsRequired = 120;
    
            Console.WriteLine("=-= Student Identification =-=");
            Console.WriteLine(pupils["Helene Mukoko"]);
            Console.WriteLine(pupils[m1]);
            Console.WriteLine(
    		"--------------------------------------------------");
    
            Console.WriteLine("=-= Student Identification =-=");
            Console.WriteLine(pupils[330647]);
            Console.WriteLine(pupils[m2]);
            Console.WriteLine(
    		"--------------------------------------------------");
            Console.WriteLine();
    
            return 0;
        }
    }
    This would produce:
    =-= Student Identification =-=
    Student #:     304850
    Full Name:     Helene Mukoko
    Gender:        Female
    Major: Computer Sciences - 120 Credits Required
    --------------------------------------------------
    =-= Student Identification =-=
    Student #:     330647
    Full Name:     Armand Essono
    Gender:        Male
    Major: Information Technology - 120 Credits Required
    --------------------------------------------------
    
    Press any key to continue . . .
  • If one property takes only one parameter, the other(s) can take more than one parameter. An indexed property can take different parameters of primitive types as seen in the previous lesson. A property can also take two or more classes as parameters. An indexed property can also take a mix of primitive and class types as parameters.
    Here are examples:
     
    using System;
    
    public enum Classification
    {
        Female,
        Male,
        Unknown
    }
    
    public class Student
    {
        public long StudentID;
        public string FirstName;
        public string LastName;
        public Classification Gender;
    
        public Student()
        {
        }
    
        public Student(long id)
        {
            this.StudentID = id;
        }
    
        public override string ToString()
        {
            return "Student ID:  " + StudentID +
                   "\nFirst Name:  " + FirstName +
                   "\nLast Name:   " + LastName +
                   "\nGender:      " + Gender;
        }
    }
    
    public enum CourseDelivery
    {
        FaceToFace,
        Online,
        Both // Student Choose
    }
    
    public class Course
    {
        public string  ShortName;
        public string  LongName;
        public string Description;
        public int Credits;
        public CourseDelivery DeliveryMode;
    
        public Course()
        {
        }
    
        public Course(string name)
        {
            ShortName = name;
        }
    
        public override string ToString()
        {
            return "Course:      " + ShortName +
                   "\nFull Name:   " + LongName +
                   "\nCredits:     " + Credits +
                   "\nDescription: " + Description +
                   "\nDelivery:    " + DeliveryMode;
        }
    }
    
    public class SchoolRegistration
    {
        Student[] students = new Student[50];
        Course[] classes = new Course[3];
    
        // This indexer takes a student id and 
        // returns the student information
        public Student this[long id]
        {
            get
            {
                for (int i = 0; i < students.Length; i++)
                {
                    if (id == students[i].StudentID)
                        return students[i];
                }
                // Unknown student or the number was not found
                return null;
            }
        }
    
        // This indexer takes a course short name and 
        // it produces a summary of the course information
        public Course this[string name]
        {
            get
            {
                for (int i = 0; i < classes.Length; i++)
                {
                    if (name == classes[i].ShortName)
                        return classes[i];
                }
    
                // Unknown course
                return null;
            }
        }
    
        public string this[Course ToAttend, Student registrant]
        {
            get
            {
                // First check that the class exists
                for (int i = 0; i < classes.Length; i++)
                {
                    if (ToAttend.ShortName == classes[i].ShortName)
                    {
                        // If the class exists, then check if the student exists
                        for (int j = 0; j < students.Length; j++)
                        {
                            if (registrant.StudentID == students[j].StudentID)
                            {
                            return "Student Identification --\n   Student ID: " +
                                       students[j].StudentID +
                                     "\n   Full Name:  " + students[j].LastName +
                                       ", " + students[j].FirstName +
                                       "\nClass to Attend --\n   Course:     " +
                                       classes[i].ShortName + " - " +
                                       classes[i].LongName + " (" +
                                       classes[i].Credits + ")" +
                                       "\n   Delivery:   " +
                                       classes[i].DeliveryMode;
                            }
                        }
                    }
                }
    
                return "Invalid Registration - You may have to start over";
            }
        }
    
        // This property takes information used to register 
        // a student to a course
        // It also specifies whether the student is willing 
        // to get in the waiting list in case another students drops out
        public string this[Student stud, Course Class, bool WaitingList]
        {
            get
            {
                // Check that the student information is valie
                for (int j = 0; j < students.Length; j++)
                {
                    if (stud.StudentID == students[j].StudentID)
                    {
                        // Now that the student information has been found,
                        // check if the course information is correct
                        for (int i = 0; i < classes.Length; i++)
                        {
                            if (Class.ShortName == classes[i].ShortName)
                            {
                                // If the class exists, then check if 
    			    // the student exists
                            return "Student Identification --\n   Student ID: " +
                                       students[j].StudentID +
                                     "\n   Full Name:  " + students[j].LastName +
                                       ", " + students[j].FirstName +
                                       "\nClass to Attend --\n   Course:     " +
                                       classes[i].ShortName + " - " +
                                       classes[i].LongName + " (" +
                                       classes[i].Credits + ")" +
                                       "\n   Delivery:   " +
                                       classes[i].DeliveryMode +
                               "\nStudent is willing to get on the waiting list: "
    				   + WaitingList;
                            }
                        }
                    }
                }
    
                return "Invalid Registration - You may have to start over";
            }
        }
    
            public SchoolRegistration()
        {
            students[0] = new Student();
            students[0].StudentID = 917294;
            students[0].FirstName = "Helene";
            students[0].LastName = "Mukoko";
            students[0].Gender = Classification.Female;
    
            students[1] = new Student();
            students[1].StudentID = 283764;
            students[1].FirstName = "Patrice";
            students[1].LastName = "Katts";
            students[1].Gender = Classification.Unknown;
    
            students[2] = new Student();
            students[2].StudentID = 192046;
            students[2].FirstName = "Armand";
            students[2].LastName = "Essono";
            students[2].Gender = Classification.Male;
    
            students[3] = new Student();
            students[3].StudentID = 618268;
            students[3].FirstName = "Bertrand";
            students[3].LastName = "Yamaguchi";
            students[3].Gender = Classification.Male;
    
            students[4] = new Student();
            students[4].StudentID = 820648;
            students[4].FirstName = "Hortense";
            students[4].LastName = "McNeal";
            students[4].Gender = Classification.Female;
    
            classes[0] = new Course();
            classes[0].ShortName = "PHIL140";
            classes[0].LongName = "Philosophy - Contemporary Moral Issues";
            classes[0].Credits = 3;
            classes[0].Description = 
    		"An exploration of how philosophical analysis can be " +
                  "\n\t\ta foundation for thinking clearly about moral issues. " +
                  "\n\t\tProblems analyzed include such widely debated issues " +
                    "\n\t\tas abortion, euthanasia, the death penalty, " +
                    "\n\t\thomosexuality, pornography, reverse discrimination, " +
                  "\n\t\tbusiness ethics, sexual equality, and economic equity.";
            classes[1] = new Course();
            classes[1].ShortName = "MATH140";
            classes[1].LongName = "Calculus I";
            classes[1].Credits = 4;
            classes[1].Description =
    		"An introduction to calculus. Topics include functions, " +
              "\n\t\tthe sketching of graphs of functions, limits, continuity, " +
              "\n\t\tderivatives and applications of the derivative, definite " +
                    "\n\t\tand indefinite integrals, and calculation of area.";
            classes[2] = new Course();
            classes[2].ShortName = "ASTR100";
            classes[2].LongName = "Introduction to Astronomy";
            classes[2].Credits = 3;
            classes[2].Description = 
    		"A discussion of the major areas of astronomy. Topics " +
                "\n\t\tinclude the solar system, stars and stellar evolution, " +
                    "\n\t\tand galaxies. Current topics in astronomy are also " +
                    "\n\t\tdiscussed.";
        }
    }
    
    public class Program
    {
        static int Main()
        {
            SchoolRegistration pupils = new SchoolRegistration();
    
            Student std = new Student(917294);
            Course crs = new Course("MATH140"); 
            Console.WriteLine("================================================");
            Console.WriteLine("Student Registration");
            Console.WriteLine("------------------------------------------");
            Console.WriteLine(pupils[crs, std]);
    
            std = new Student(820648);
            crs = new Course("PHIL140");
            Console.WriteLine("================================================");
            Console.WriteLine("Student Registration");
            Console.WriteLine("------------------------------------------");
            Console.WriteLine(pupils[std, crs, true]);
    
          Console.WriteLine("================================================\n");
            return 0;
        }
    }
    This would produce:
    ================================================
    Student Registration
    ------------------------------------------
    Student Identification --
       Student ID: 917294
       Full Name:  Mukoko, Helene
    Class to Attend --
       Course:     MATH140 - Calculus I (4)
       Delivery:   FaceToFace
    ================================================
    Student Registration
    ------------------------------------------
    Student Identification --
       Student ID: 820648
       Full Name:  McNeal, Hortense
    Class to Attend --
       Course:     PHIL140 - Philosophy - Contemporary Moral Issues (3)
       Delivery:   FaceToFace
    Student is willing to get on the waiting list: True
    ================================================
    
    Press any key to continue . . .

Practical Learning: Overloading an Indexer

  1. To overload the indexer, access the PropertyListing.cs file and change it as follows:
     
    using System;
    
    namespace PropertyRental1
    {
        public class PropertyListing
        {
            public Property[] props;
    
            public Property this[int i]
            {
                get
                {
                    if ((i >= 0) && (i < 40))
                        return props[i];
                    else return null;
                }
            }
    
            public Property this[long code]
            {
                get
                {
                    for (int i = 0; i < props.Length; i++)
                        if (code == props[i].PropertyCode)
                            return props[i];
                    return null;
                }
            }
    
            public PropertyListing()
            {
                . . . No Change
            }
        }
    }
  2. Access the Program.cs file and change it as follows:
     
    using System;
    
    namespace PropertyRental2
    {
        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;
            }
        }
    }
  3. Press Ctrl + F5 to execute the application 
  4. Close the DOS window

Read/Write Indexed Properties

As done for a primitive type, you can allow the clients of your indexer to assign values to the array's elements. Once again, when defining the property, you should include a set accessor to it. In the set accessor, you should assign the value keyword to an element of the array. Here is an example:

public class SchoolRegistration
{
    Student[] std = new Student[5];

    public Student this[int i]
    {
        get { return std[i]; }
        set { std[i] = value; }
    }
}

After doing this, you can create an element of the array by applying the square brackets to the instance of the class and assigning the desired value to it. The problem with the class is that, since it may have many fields (or properties), to completely define each element, you must provide a value to the member variables of the class itself. Here is an example:

using System;

public enum Classification
{
    Female,
    Male,
    Unknown
}

public class Student
{
    public long StudentID;
    public string FirstName;
    public string LastName;
    public Classification Gender;

    public override string ToString()
    {
        string str = "Student ID: " + StudentID +
                     "\nFirst Name: " + FirstName +
                     "\nLast Name:  " + LastName +
                     "\nGender:     " + Gender;
        return str;
    }
}

public class SchoolRegistration
{
    Student[] std = new Student[5];

    public Student this[int i]
    {
        get { return std[i]; }
        set { std[i] = value; }
    }
}

public class Program
{
    static int Main()
    {
        SchoolRegistration registration = new SchoolRegistration();

        Student stud = new Student();
        stud.StudentID = 604057;
        stud.FirstName = "Gertrude";
        stud.LastName = "Monayong";
        stud.Gender = Classification.Female;
        registration[2] = stud;

        Console.WriteLine("Student Information");
        Console.WriteLine("---------------------");
        Console.WriteLine("First Name: {0}", registration[2].FirstName);
        Console.WriteLine("Last Name:  {0}", registration[2].LastName);
        Console.WriteLine("Gender:     {0}\n",registration[2].Gender);
         
        return 0;
    }
}

This would produce:

Student Information
---------------------
First Name: Gertrude
Last Name:  Monayong
Gender:     Female

Press any key to continue . . .
 

Previous Copyright © 2007-2012 FunctionX Home