Home

Topics on Indexed Properties

 

Multi-Parameterized Indexed Properties

The indexed properties we have used so far were taking only one parameter. You can create an indexed property whose array uses more than one dimension. To start an indexed property that would use various parameters, first declare the array. After declaring the array, create a default property that takes the parameters. Here is an example for an indexed property that relates to a two-dimensional array:

public ref class CNumbers
{
    array<double, 2> ^ nbr;

public:
    property double default[int, int]
    {      
    }
};

In the body of an accessor (get or set), use the parameter as appropriately as you see fit. At a minimum, for a get accessor, you can return the value of the array using the parameters based on the rules of a two-dimensional array. This can be done as follows:

public ref class CNumbers
{
    array<double, 2> ^ nbr;

public:
    property double default[int, int]
    {
        double get(int i, int j) { return nbr[i,j]; }
    }
};

After creating the property, you can access each element of the array by applying the square brackets to an instance of the class. Here is an example:

using namespace System;

public ref class CNumbers
{
    array<double, 2> ^ nbr;

public:
	property double default[int, int]
    {
        double get(int i, int j) { return nbr[i,j]; }
    }

    CNumbers()
	{
		nbr = gcnew array<double, 2>(2, 4);

        nbr[0, 0] = 927.93;
        nbr[0, 1] = 45.155;
        nbr[0, 2] = 2.37094;
        nbr[0, 3] = 73475.25;
        nbr[1, 0] = 186.72;
        nbr[1, 1] = 82.350;
        nbr[1, 2] = 712734.95;
        nbr[1, 3] = 3249.0057;
	}
};

int main()
{
    CNumbers ^ nbrs = gcnew CNumbers;

    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            double value = nbrs[i, j];
            Console::WriteLine(L"Number [{0}][{1}]: {2}", i, j, value);
        }

        Console::WriteLine();
    }

    return 0;
}

Remember that one of the most valuable features of an indexed property is that, when creating it, you can make it return any primitive type and you can make it take any parameter of your choice. Also, the parameters of a multi-parameter indexed property don't have to be the same type. One can be a character while the other is a bool type; one can be a double while the other is a short, one can be an integer while the other is a string. When defining the property, you must apply the rules of both the methods and the arrays. Here is an example of a property that takes an integer and a string:

using namespace System;

public ref class CCatalog
{
    array<long> ^ nbrs;
    array<String ^> ^  names;

public:
	property double default[long, String ^]
    {
        double get(long nbr, String ^ name)
        {
            if( (nbr == nbrs[0]) && (name == names[0]) )
                return 275.25;
            else if( (nbr == nbrs[1]) && (name == names[1]) )
                return 18.75;
            else if( (nbr == nbrs[2]) && (name == names[2]) )
                return 50.00;
            else if( (nbr == nbrs[3]) && (name == names[3]) )
                return 65.35;
            else if( (nbr == nbrs[4]) && (name == names[4]) )
                return 25.55;
            else
                return 0.00;
        }
    }

    CCatalog()
    {
        nbrs = gcnew array<long>(5);

        nbrs[0] = 273974;
        nbrs[1] = 539759;
        nbrs[2] = 710234;
        nbrs[3] = 220685;
        nbrs[4] = 192837;

        names = gcnew array<String ^>(5);

        names[0] = L"Women Double-faced wool coat";
        names[1] = L"Men Cotton Polo Shirt";
		names[2] = L"Children Cable-knit Sweater";
		names[3] = L"Women Floral Silk Tank Blouse";
        names[4] = L"Girls Jeans with Heart Belt";
    }
};

int main()
{
    CCatalog ^ cat = gcnew CCatalog;

    long itemNumber = 539759;
    String ^ itemDescription = L"Men Cotton Polo Shirt";
    double price = cat[itemNumber, itemDescription];

    Console::WriteLine(L"Item #:      {0}", itemNumber);
    Console::WriteLine(L"Description: {0}", itemDescription);
    Console::WriteLine(L"Unit Price:  {0}", price);

    Console::WriteLine();
    return 0;
}

This would produce:

Item #:      539759
Description: Men Cotton Polo Shirt
Unit Price:  18.75

Press any key to continue . . .

In the above example, we first declared the variables to be passed as parameters to the indexed property. You can also pass the parameter(s) directly to the instance of the class. Here is an example:

int main()
{
    CCatalog ^ cat = gcnew CCatalog;

    double price = cat[220685, L"Women Floral Silk Tank Blouse"];

    Console::WriteLine(L"Item #:      220685");
    Console::WriteLine(L"Description: {Women Floral Silk Tank Blouse");
    Console::WriteLine(L"Unit Price:  {0}", price);

    Console::WriteLine();
    return 0;
}

Just as you can create a two-dimensional indexed property, you can also create a property that takes more than two parameters. Once again, it is up to you to decide what type of parameter would be positioned where in the square brackets. Here is an example of an indexed property that takes three parameters:

using namespace System;

public ref class CCatalog
{
public:
    property String ^ default[long, String ^, double]
    {
        String ^ get(long nbr, String ^ name, double price)
        {
            return L"Item #:      " + nbr.ToString() + L"\n" +
                   L"Description: " + name + "\n" +
                   L"Unit Price:  " + price.ToString(L"C");
        }
    }
};

int main()
{
    CCatalog ^ cat = gcnew CCatalog;

    Console::WriteLine(L"Item Description");
    Console::WriteLine(cat[220685, L"Women Floral Silk Tank Blouse", 50.00]);

    Console::WriteLine();
    return 0;
}

Overloading an Indexed Property

An indexed property borrows various characteristics of a method. One of them is the ability to create various indexers in the same class but all of them must have the same name: default. Still, the various indexed properties of a class can return the same type of value. Because of this, when creating the indexed properties, you must find a way to distinguish them. One way you can do this, as seen with function or method overloading, consists of passing a different type of parameter to each indexed property. This is referred to as overloading.

To overload the default property, if two indexed properties take only one parameter, each must take a different (data) type of parameter than the other. Here is an example:

using namespace System;

public ref class CStudentIdentifications
{
    array<int> ^ studentIDs;
    array<String ^> ^  fullnames;

    // This property takes a student ID, as an integer,
    // and it produces his/her name
public:
    property String ^ default[int]
    {
        String ^ get(int i)
        {
            for(int i = 0; i < studentIDs->Length; i++)
                if( i == studentIDs[i] )
                    return fullnames[i];

            return L"Unknown Student";
        }
    }

    // This property takes a student name, as a string,
    // and it produces his/her student ID
    property int default[String ^]
    {
        int get(String ^ name)
        {
            for(int i = 0; i < fullnames->Length; i++)
                if( name == fullnames[i] )
                    return studentIDs[i];

            return 0;
        }
    }

    CStudentIdentifications()
    {
        studentIDs = gcnew array<int>(6);

        studentIDs[0] = 39472;
        studentIDs[1] = 13957;
        studentIDs[2] = 73957;
        studentIDs[3] = 97003;
        studentIDs[4] = 28947;
        studentIDs[5] = 97395;

        fullnames = gcnew array<String ^>(6);

        fullnames[0] = L"Paul Bertrand Yamaguchi";
        fullnames[1] = L"Ernestine Ngovayang";
        fullnames[2] = L"Patricia L Katts";
        fullnames[3] = L"Helene Mukoko";
        fullnames[4] = L"Joan Ursula Hancock";
        fullnames[5] = L"Arlette Mimosa";
    }
};

int main()
{
    CStudentIdentifications ^ std = gcnew CStudentIdentifications;

    Console::WriteLine(L"Student Identification");
    Console::WriteLine(L"Student ID: 39472");
    Console::WriteLine(L"Full Name:  {0}\n", std[39472]);

    Console::WriteLine(L"Student Identification");
    Console::WriteLine(L"Full Name:  Joan Ursula Hancock");
    Console::WriteLine(L"Student ID: {0}\n", std[L"Joan Ursula Hancock"]);

    return 0;
}

This would produce:

Student Identification
Student ID: 39472
Full Name:  Paul Bertrand Yamaguchi

Student Identification
Full Name:  Joan Ursula Hancock
Student ID: 28947

Press any key to continue . . .

An indexed property combines the features of an array and those of a method that takes one or more parameters. As an array, an indexed property can use one or more dimensions as we have seen so far. Borrowing the features of a method, an indexed property can take one or more parameters and it can return a value. Besides passing different types of parameters to various indexed properties, you can create some of them that take more than one parameter. Here is an example:

using namespace System;

public ref class CCatalog
{
    array<long> ^ nbrs;
    array<String ^> ^ names;
    array<double> ^ prices;

public:
    // This property produces the name of an item, as a string,
    // if it is given the item #, as a number
    property String ^ default[long]
    {
        String ^ get(long nbr)
        {
            for (int i = 0; i < nbrs.Length; i++)
                if (nbr == nbrs[i])
                    return names[i];

            return L"Unknown Item";
        }
    }

    // This property produces the price of the item, as a number,
    // if it is given the item name and its number
    property double default[String ^, long]
    {
        double get(String ^ name, long nbr)
        {
            for (int i = 0; i < 5; i++)
                if ((nbr == nbrs[i]) && (name == names[i]))
                    return prices[i];

            return 0.00;
        }
    }

    CCatalog()
    {
        nbrs = gcnew array<long>(5);
        nbrs[0] = 273974;
        nbrs[1] = 539759;
        nbrs[2] = 710234;
        nbrs[3] = 220685;
        nbrs[4] = 192837;

        names = gcnew array<String ^>(5);
        names[0] = L"Women Double-faced wool coat";
        names[1] = L"Men Cotton Polo Shirt";
        names[2] = L"Children Cable-knit Sweater";
        names[3] = L"Women Floral Silk Tank Blouse";
        names[4] = L"Girls Jeans with Heart Belt";

        prices = gcnew array<double>(5);
        prices[0] = 275.25;
        prices[1] = 18.75;
        prices[2] = 50.00;
        prices[3] = 65.35;
        prices[4] = 25.55;
    }
};

int main()
{
    CCatalog ^ cat = gcnew CCatalog;

    Console::WriteLine(L"Item Identification");
    Console::WriteLine(L"Item #:      539759");
    Console::WriteLine(L"Unit Price:  {0}\n", cat[539759]);

    Console::WriteLine(L"Item Identification");
    Console::WriteLine(L"Item #:      192837");
    Console::WriteLine(L"Description: Girls Jeans with Heart Belt");
    Console::WriteLine(L"Unit Price:  {0}\n",
            cat["Girls Jeans with Heart Belt", 192837]);

    return 0;
}

This would produce:

Item Identification
Item #:      539759
Unit Price:  Men Cotton Polo Shirt

Item Identification
Item #:      192837
Description: Girls Jeans with Heart Belt
Unit Price:  25.55

Press any key to continue . . .
 

Previous Copyright © 2007-2012 FunctionX Next