Fundamentals of Indexed Properties and Classes
Before designing an indexer that is class-based, first
create the class that will be used as the data type. The class can be simple or
complex as you judge it necessary. Here is an example of a simple class:
public class Student { public string FirstName; public string LastName; public int Gender; }
When creating the class that will host the indexed property,
declare an array field for the class. Then, create the this property with
the desired accessor(s). Here is an example:
public class Student
{
public string FirstName;
public string LastName;
public int Gender;
}
public class SchoolRegistration
{
Student[] std = new Student[5];
public Student this[int i]
{
get { return std[i]; }
}
}
After creating the indexing class, you can use it and access
the indexer. For example, you can retrieve its value(s). Here is an example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
public class Student
{
public string FirstName;
public string LastName;
public int Gender;
}
public class SchoolRegistration
{
Student[] std = new Student[5];
public Student this[int i]
{
get { return std[i]; }
}
public SchoolRegistration()
{
std[0] = new Student();
std[0].FirstName = "Alfredo";
std[0].LastName = "Olmos";
std[0].Gender = 2;
std[1] = new Student();
std[1].FirstName = "Patricia";
std[1].LastName = "Katts";
std[1].Gender = 1;
std[2] = new Student();
std[2].FirstName = "Josiane";
std[2].LastName = "Euler";
std[2].Gender = 1;
std[3] = new Student();
std[3].FirstName = "Joan";
std[3].LastName = "Jones";
std[3].Gender = 3;
std[4] = new Student();
std[4].FirstName = "George";
std[4].LastName = "Paulson";
std[4].Gender = 2;
}
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var pupils = new SchoolRegistration();
Response.Write("<pre>");
for (var i = 0; i < 5; i++)
{
Student pupil = pupils[i];
Response.Write("=====================<br />");
Response.Write("Student Information<br />");
Response.Write("---------------------<br />");
Response.Write("First Name: " + pupil.FirstName + "<br />");
Response.Write("Last Name: " + pupil.LastName + "<br />");
Response.Write("Gender: " +
(pupil.Gender == 1 ? "Female" :
(pupil.Gender == 2 ? "Male" : "Unknown")) + "<br />");
Response.Write("<p></p>");
}
Response.Write("</pre>");
}
}
This would produce:
As done for primitive types, an indexer can take a
parameter other than an integer. In some cases, you may use your class or a
class created by someone else and need to access an element of the array without
information other than its index. Consider the following code:
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[50];
public Student this[...]
{
}
}
Previously, we saw that you could create an indexer that
takes a type than an integer. For example, we saw that a string could be used as
an index.
By now, we know that a basic indexed property produces (or
all the indexed properties we have studied so far produce) only one value. If
you have a class that has only one field, this would be enough. In reality, most
of the time, a class has many fields. In such a case, when you create an indexer
, you need to be able to refer to one exact element of the array. To make this
possible, you must define a way to point to the particular element you want. One
way you can do this is to use one field of the class as a reference. This is
better if that field holds unique values among the other elements of the array.
For our Student class, we could use the StudentID field (because we will make
sure that each student has a unique ID). You can start the property as follows:
public class SchoolRegistration
{
Student[] std = new Student[5];
public Student this[long id]
{
}
}
When a user uses this property, he or she must provide a
value that uniquely identifies an element of the array. You in turn, when you
get this value, you can search for it in the array. If you find it and the array
has a get accessor, you can then return the desired but appropriate
value. Here is how this can be done:
public class SchoolRegistration
{
Student[] students = new Student[50];
public Student this[long id]
{
get
{
for (int i = 0; i < students.Length; i++)
{
if (students[i].StudentID == id)
return students[i];
}
// Unknown student or the number was not found
return null;
}
}
}
After creating the indexer, you can use it. Once again, you
must follow the rules of a method that takes an argument and returns a value
other than void. In this case, the indexer must take a string and it must
return a Student object. Here is an example:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; 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[] students = new Student[50]; public Student this[long id] { get { for (int i = 0; i < students.Length; i++) { if (students[i].StudentID == id) return students[i]; } // Unknown student or the number was not found return null; } } 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; } } public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var pupils = new SchoolRegistration(); var pupil = pupils[820648]; Response.Write("<pre>=====================<br />"); Response.Write("Student Information<br />"); Response.Write("---------------------<br />"); Response.Write("First Name: " + pupil.FirstName + "<br />"); Response.Write("Last Name: " + pupil.LastName + "<br />"); Response.Write("Gender: " + pupil.Gender + "<br />"); pupil = pupils[192046]; Response.Write("<br />====================="); Response.Write("<br />Student Information"); Response.Write("<br />---------------------"); Response.Write("<br />First Name: " + pupil.FirstName); Response.Write("<br />Last Name: " + pupil.LastName); Response.Write("<br />Gender: " + pupil.Gender + "</pre>"); } } |
|
||||||
|
This would produce:
|
|
Topics on Indexed Properties 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:
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; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; 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 partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var pupils = new SchoolRegistration(); var pupil = new Student(); pupil.StudentID = 820648; var strStudent = pupils[pupil]; Response.Write("<pre>=====================<br />"); Response.Write("Student Information<br />"); Response.Write("---------------------<br />"); Response.Write(strStudent); pupil.StudentID = 192046; strStudent = pupils[pupil]; Response.Write("<br />====================="); Response.Write("<br />Student Information"); Response.Write("<br />---------------------<br />"); Response.Write(strStudent); Response.Write("<br />=====================</pre>"); } }
This would produce:
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.
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
- 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. An indexer can also take two or more classes as parameters. An indexed property can also take a mix of primitive and class types as parameters
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; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; 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 partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var registration = new SchoolRegistration(); var stud = new Student(); stud.StudentID = 604057; stud.FirstName = "Gertrude"; stud.LastName = "Monayong"; stud.Gender = Classification.Female; registration[2] = stud; Response.Write("<pre>=====================<br />"); Response.Write("Student Information<br />"); Response.Write("---------------------<br />"); Response.Write("First Name: " + registration[2].FirstName + "<br />"); Response.Write("Last Name: " + registration[2].LastName + "<br />"); Response.Write("Gender: " + registration[2].Gender); Response.Write("<br />=====================</pre>"); } }
This would produce:
No comments :
Post a Comment