public:
. . . No Change
virtual property Object ^ default[int]
{
Object ^ get(int index) { return objects[index]; }
void set(int index, Object ^ value)
{
objects[index] = value;
}
}
. . . No Change
};
After creating this property, you can then access an item
using its index and applying the [] operator on its instance. Remember that if
you want to use for each, you must appropriately implement the IEnumerable::GetEnumerator()
method.
Practical
Learning: Identifying this Item in the Collection
|
|
- Access the Properties.h header file
- In the Scopes combo box of the Code Editor, select CProperties::default
- In the Functions combo box, select get
- Change the default property as
follows:
#pragma once
#include "RentalProperty.h"
using namespace System;
using namespace System::Collections;
public ref class CProperties : public IList
{
private:
array<Object ^> ^ RentalProperties;
int counter;
public:
. . . No Change
virtual property Object ^ default[int]
{
Object ^ get(int index) { return RentalProperties[index]; }
void set(int index, Object ^ value)
{
RentalProperties[index] = value;
}
}
. . . No Change
};
|
- Access the Exercise.cpp source file and change the section of the for loop
as follows:
#include "RentalProperty.h"
#include "Properties.h"
using namespace System;
int main()
{
. . . No Change
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for(int i = 0; i < properties->Count; i++)
{
CRentalProperty ^ prop =
dynamic_cast<CRentalProperty ^>(properties[i]);
Console::WriteLine(L"---------------------------");
Console::WriteLine(L"{0}. Property Details",
(i+1).ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
}
Console::WriteLine(L"================================");
return 0;
}
|
- Execute the application to see the result
- Close the DOS window
- Open the Properties.h header file
- To be able to use for each, make the following changes:
#pragma once
#include "RentalProperty.h"
using namespace System;
using namespace System::Collections;
public ref class CProperties : public IList, IEnumerator
{
private:
array<Object ^> ^ RentalProperties;
int counter;
int cur;
public:
CProperties(void);
virtual property int Count
{
int get() { return counter; }
}
virtual property bool IsSynchronized
{
bool get() { return false; }
}
virtual property Object ^ SyncRoot
{
Object ^ get() { return this; }
}
virtual property bool IsFixedSize
{
bool get() { return false; }
}
virtual property bool IsReadOnly
{
bool get() { return false; }
}
virtual property Object ^ default[int]
{
Object ^ get(int index) { return RentalProperties[index]; }
void set(int index, Object ^ value)
{
RentalProperties[index] = value;
}
}
property Object ^ Current
{
virtual Object ^ get()
{
try {
return this[cur];
}
catch(IndexOutOfRangeException ^)
{
Console::WriteLine(L"The current rental property can be "
L"accessed only within a valid range ");
return nullptr;
}
}
}
virtual void Reset();
virtual bool MoveNext();
virtual void CopyTo(Array ^, int);
virtual IEnumerator ^ GetEnumerator(void);
. . . No Change
};
|
- Open the Properties.cpp source file and make the following changes:
#include "Properties.h"
CProperties::CProperties(void)
: counter(0), cur(-1)
{
RentalProperties = gcnew array<Object ^>(5);
}
void CProperties::CopyTo(Array ^, int)
{
}
void CProperties::Reset()
{
cur = -1;
}
bool CProperties::MoveNext()
{
cur++;
if( cur < Count )
return true;
else
return false;
}
IEnumerator ^ CProperties::GetEnumerator(void)
{
return this;
}
. . . No Change
|
- Open the Exercise.cpp source file and make the following changes:
#include "RentalProperty.h"
#include "Properties.h"
using namespace System;
int main()
{
. . . No Change
int i = 1;
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for each(CRentalProperty ^ prop in properties)
{
Console::WriteLine(L"---------------------------");
Console::WriteLine(L"{0}. Property Details", i.ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
i++;
}
Console::WriteLine(L"================================");
return 0;
}
|
- Close the DOS window
Checking the Existence of an Item
|
|
One of the routine operations you can perform on a list is
to find out whether it contains a certain item. To assist you with this
operation, the IList interface is equipped with a method named Contains. Its syntax is:
bool Contains(Object ^ item);
This method takes as argument the item to look for. If the
item is found in the list, the method returns true. If no item is found in the
collection, this method returns false.
Here is an example of implementing this method:
public ref class CObjects : public IList
{
private:
int items;
array<Object ^> ^ objects;
public:
. . . No Change
virtual int Add(Object ^);
virtual void Insert(int, Object ^);
virtual bool Contains(Object ^);
};
. . . No Change
bool CObjects::Contains(Object ^ value)
{
for(int i = 0; i < Count; i++
if( objects[i] == value )
return true;
return false;
}
This method calls the Equals() method of the objects
that make up the collection (in our example, that would be the objects array) to
find out whether the item argument exists in the collection. If this
method produces a wrong result especially if you are using your own class to
represent the item, you may have to override your own Equals()
method.
Practical
Learning: Checking the Existence of an Item
|
|
- Open the RentalProperty.h header file and declare a virtual Equals()
method as
follows:
#pragma once
using namespace System;
. . . No Change
[Serializable]
public ref class CRentalProperty
{
private:
. . . No Change
public:
. . . No Change
public:
virtual bool Equals(CRentalProperty ^);
// This constructor is used to create
// default values for a property
CRentalProperty(void);
};
|
- Access the RentalProperty.cpp source file and implement the method as
follows:
#include "RentalProperty.h"
CRentalProperty::CRentalProperty(void)
{
propCode = 0;
type = PropertyTypes::Unknown;
cond = PropertyConditions::Unknown;
beds = 0;
baths = 0.0;
val = 0.00;
}
bool CRentalProperty::Equals(CRentalProperty ^ prop)
{
if( (propCode == prop->PropertyCode) &&
(type == prop->PropertyType) &&
(cond == prop->PropertyCondition) &&
(beds == prop->Bedrooms) &&
(baths == prop->Bathrooms) &&
(val == prop->MonthlyRent) )
return true;
else
return false;
}
|
- Open the Properties.cpp source file
- In the Functions combo box, select Contains and implement the method as
follows:
// This method is used to find out whether the item
// passed as argument exists in the collection
bool CProperties::Contains(Object ^ value)
{
bool found = false;
for(int i = 0; i < Count; i++)
if( dynamic_cast<CRentalProperty ^>(
this[i])->Equals(dynamic_cast<CRentalProperty ^>(value)) )
found = true;
return found;
}
|
- Open the Exercise.cpp source file and make the following changes:
#include "RentalProperty.h"
#include "Properties.h"
using namespace System;
int main()
{
CProperties ^ properties = gcnew CProperties;
CRentalProperty ^ rental = nullptr;
rental = gcnew CRentalProperty;
rental->PropertyCode = 737495;
rental->PropertyType = PropertyTypes::Apartment;
rental->PropertyCondition = PropertyConditions::Good;
rental->Bedrooms = 1;
rental->Bathrooms = 1;
rental->MonthlyRent = 950.00;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 293749;
rental->PropertyType = PropertyTypes::SingleFamily;
rental->PropertyCondition = PropertyConditions::Excellent;
rental->Bedrooms = 5;
rental->Bathrooms = 3.5;
rental->MonthlyRent = 2550.75;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 224006;
rental->PropertyType = PropertyTypes::Apartment;
rental->PropertyCondition = PropertyConditions::Excellent;
rental->Bedrooms = 2;
rental->Bathrooms = 1;
rental->MonthlyRent = 1250.55;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 197249;
rental->PropertyType = PropertyTypes::Townhouse;
rental->PropertyCondition = PropertyConditions::BadShape;
rental->Bedrooms = 4;
rental->Bathrooms = 2.5;
rental->MonthlyRent = 1750.65;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 592795;
rental->PropertyType = PropertyTypes::SingleFamily;
rental->PropertyCondition = PropertyConditions::Good;
rental->Bedrooms = 3;
rental->Bathrooms = 2.00;
rental->MonthlyRent = 1870.35;
properties->Add(rental);
int i = 1;
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for each(CRentalProperty ^ prop in properties)
{
Console::WriteLine(L"---------------------------");
Console::WriteLine(L"{0}. Property Details", i.ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
i++;
}
Console::WriteLine(L"================================");
CRentalProperty ^ item1 = gcnew CRentalProperty;
item1->PropertyCode = 293749;
item1->PropertyType = PropertyTypes::SingleFamily;
item1->PropertyCondition = PropertyConditions::Excellent;
item1->Bedrooms = 5;
item1->Bathrooms = 3.5;
item1->MonthlyRent = 2550.75;
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
Console::WriteLine(L"-=- Sample Property -=-");
Console::WriteLine(L"Property #: {0}",
item1->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
item1->PropertyType);
Console::WriteLine(L"Condition: {0}",
item1->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
item1->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
item1->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
item1->MonthlyRent);
Console::WriteLine(L"-------------------------------------------");
if( properties->Contains(item1) == true )
Console::WriteLine("That property already exists in the listing");
else
Console::WriteLine("The property was not found in our database");
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
CRentalProperty ^ item2 = gcnew CRentalProperty;
item2->PropertyCode = 290004;
item2->PropertyType = PropertyTypes::SingleFamily;
item2->PropertyCondition = PropertyConditions::Excellent;
item2->Bedrooms = 5;
item2->Bathrooms = 3.5;
item1->MonthlyRent = 2550.75;
Console::WriteLine(L"-=- Sample Property -=-");
Console::WriteLine(L"Property #: {0}",
item2->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
item2->PropertyType);
Console::WriteLine(L"Condition: {0}",
item2->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
item2->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
item2->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
item2->MonthlyRent);
Console::WriteLine(L"-------------------------------------------");
if( properties->Contains(item2) == true )
Console::WriteLine("That property already exists in the listing");
else
Console::WriteLine("The property was not found in our database");
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
return 0;
}
|
- Execute the application to see the result:
<+> Solas Properties Rental <+>
<-> Properties Listing <->
---------------------------
1. Property Details
Property #: 737495
Property Type: Apartment
Condition: Good
Bedrooms: 1
Bathrooms: 1
Monthly Rent: 950
---------------------------
2. Property Details
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
---------------------------
3. Property Details
Property #: 224006
Property Type: Apartment
Condition: Excellent
Bedrooms: 2
Bathrooms: 1
Monthly Rent: 1250.55
---------------------------
4. Property Details
Property #: 197249
Property Type: Townhouse
Condition: BadShape
Bedrooms: 4
Bathrooms: 2.5
Monthly Rent: 1750.65
---------------------------
5. Property Details
Property #: 592795
Property Type: SingleFamily
Condition: Good
Bedrooms: 3
Bathrooms: 2
Monthly Rent: 1870.35
================================
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
-------------------------------------------
That property already exists in the listing
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 290004
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 0
-------------------------------------------
The property was not found in our database
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
Press any key to continue . . .
|
- Close the DOS window
Getting the Index of an Item
|
|
The Contains method is used to check whether a particular item (already)
exists in the collection. If you know that a certain item exists in the
collection but you don't know its index inside the list, the IList interface can
assist you through a method named IndexOf. Its syntax is:
int IndexOf(Object^ value);
This method takes as argument the item to look for in the list. If the item
is found in the collection, the method returns its index. If there is no item
defined like that, the method returns -1. Here is an example of implementing
this method:
using namespace System;
using namespace System::Collections;
public ref class CObjects : public IList
{
private:
int items;
array<Object ^> ^ objects;
public:
. . . No Change
virtual int IndexOf(Object ^);
};
. . . No Change
int CObjects::IndexOf(Object ^ value)
{
for(int i = 0; i < Count; i++
if( objects[i] == value )
return i;
return -1;
}
This method calls the Equals() method of the objects that make up the
collection (in our example, that would be the objects array) to find out whether
the item argument exists in the collection. If this method produces a
wrong result especially if you are using your own class to represent the item,
you may have to override your own Equals() method.
Practical
Learning: Getting the Index of an Item
|
|
- Open the Properties.cpp source file.
In the Functions combo box, select IndexOf and implement the method as
follows:
// This method is used to check whether the item passed as
// argument exists in the collection. If so, it returns its index
int CProperties::IndexOf(Object ^ value)
{
int custIndex = -1;
for(int i = 0; i < Count; i++)
{
if( dynamic_cast<CRentalProperty ^>(
this[i])->Equals(dynamic_cast<CRentalProperty ^>(value)) )
{
custIndex = i;
break;
}
}
return custIndex;
}
|
- Open the Exercise.cpp source file and make the following changes:
#include "RentalProperty.h"
#include "Properties.h"
using namespace System;
int main()
{
. . . No Change
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
CRentalProperty ^ item3 = gcnew CRentalProperty;
item3->PropertyCode = 224006;
item3->PropertyType = PropertyTypes::Apartment;
item3->PropertyCondition = PropertyConditions::Excellent;
item3->Bedrooms = 2;
item3->Bathrooms = 1;
item3->MonthlyRent = 1250.55;
Console::WriteLine(L"-=- Sample Property -=-");
Console::WriteLine(L"Property #: {0}",
item3->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
item3->PropertyType);
Console::WriteLine(L"Condition: {0}",
item3->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
item3->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
item3->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
item3->MonthlyRent);
Console::WriteLine(L"The index of this property is: {0}",
properties->IndexOf(item3));
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
return 0;
}
|
- Execute the application to see the result:
<+> Solas Properties Rental <+>
<-> Properties Listing <->
---------------------------
1. Property Details
Property #: 737495
Property Type: Apartment
Condition: Good
Bedrooms: 1
Bathrooms: 1
Monthly Rent: 950
---------------------------
2. Property Details
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
---------------------------
3. Property Details
Property #: 224006
Property Type: Apartment
Condition: Excellent
Bedrooms: 2
Bathrooms: 1
Monthly Rent: 1250.55
---------------------------
4. Property Details
Property #: 197249
Property Type: Townhouse
Condition: BadShape
Bedrooms: 4
Bathrooms: 2.5
Monthly Rent: 1750.65
---------------------------
5. Property Details
Property #: 592795
Property Type: SingleFamily
Condition: Good
Bedrooms: 3
Bathrooms: 2
Monthly Rent: 1870.35
================================
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
-------------------------------------------
That property already exists in the listing
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 290004
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 0
-------------------------------------------
The property was not found in our database
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 224006
Property Type: Apartment
Condition: Excellent
Bedrooms: 2
Bathrooms: 1
Monthly Rent: 1250.55
The index of this property is: 2
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
Press any key to continue . . .
|
- Close the DOS window
|
|