Header File: BookList.h #pragma once using namespace System; using namespace System::Collections; public ref class CBookList : public IList { private: int counter; array<Object ^> ^ objects; public: . . . No Change virtual property Object ^ default[int] { Object ^ get(int index) { return objects[index]; } void set(int index, Object ^ value) { objects[index] = value; } } }; 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.
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
One of the most valuables features of the C# is the ability to use the for each loop to enumerate the members of a collection. To make this possible, you must implement the IEnumerator interface in your collection class. Following the rules of interface implementation, you must override the members of IEnumerator.
One of the routine operations you can perform on a list is to find out whether it contains a certain value. To assist you with this operation, the System::Collections::IList interface is equipped with a method named Contains. Its syntax is: bool Contains(object value); This method takes as argument the value to look for. If the value is found in the list, the method returns true. If no value is found in the collection, this method returns false. Here is an example of implementing this method: Header File: BookList.h #pragma once using namespace System; using namespace System::Collections; public ref class CBookList : public IList { private: int counter; array<Object ^> ^ objects; public: . . . No Change virtual bool Contains(Object ^ value); }; Source File: BookList.cpp #include "BookList.h" . . . No Change bool CBookList::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 list to find out whether the value 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.
The System::Collections::IList::Contains() method is used to check whether a particular value (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 value to look for in the list. If the value is found in the collection, the method returns its index. If there is no value defined like that, the method returns -1. Here is an example of implementing this method: Header File: BookList.h #pragma once using namespace System; using namespace System::Collections; public ref class CBookList : public IList { private: int counter; array<Object ^> ^ objects; public: . . . No Change virtual bool Contains(Object ^ value); virtual int IndexOf(Object ^ value); }; Source File: BookList.cpp #include "BookList.h" . . . No Change int CBookList::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 to find out whether the value argument exists in the list. If this method produces a wrong result, especially if you are using your own class to represent the value, you may have to override your own Equals() method.
If a value is not necessary in your list, you can delete it. Probably the simplest way to delete a value is to specify its position in the list. To support this operation, both the System::Collections::IList and the System::Collections::Generic::IList interfaces are equipped with a method named RemoveAt. The syntax of the RemoveAt() method is is the same for both interfaces and it is: void RemoveAt(int index); This method takes as argument the index of the value to be removed. Here is an example: Header File: BookList.h #pragma once using namespace System; using namespace System::Collections; public ref class CBookList : public IList { private: int counter; array<Object ^> ^ objects; public: . . . No Change virtual bool Contains(Object ^ value); virtual int IndexOf(Object ^ value); virtual void RemoveAt(int index); }; Source File: BookList.cpp #include "BookList.h" . . . No Change void CBookList::RemoveAt(int index) { if ((index >= 0) && (index < Count)) { for (int i = index; i < Count - 1; i++) objects[i] = objects[i + 1]; counter--; } }
The problem with deleting a value based on its index is that, if you are not sure, you could delete the wrong value. An alternative is to first precisely define the value you want to get rid of, and then hand the value itself to the compiler that would remove it. To support this approach, the System::Collections::IList interface is equipped with a method named Remove() and whose syntax is: void Remove(Object^ value); This method takes as argument the value to be deleted. This means that the compiler will first look for the value in the list. If it finds that value, it removes it. If there is no value like that, nothing happens (the compiler doesn't throw an exception. Here is an example of implementing this method: Header File: BookList.h #pragma once using namespace System; using namespace System::Collections; public ref class CBookList : public IList { private: int counter; array<Object ^> ^ objects; public: . . . No Change virtual bool Contains(Object ^ value); virtual int IndexOf(Object ^ value); virtual void RemoveAt(int index); virtual void Remove(Object ^ value); }; Source File: BookList.cpp #include "BookList.h" . . . No Change void CBookList::Remove(Object ^ value) { RemoveAt(IndexOf(value)); }
To remove all value from a list at once, you can implement Clear() method of the System::Collections::IList interface. Its syntax is: void Clear(); Here is an example of implementing it: Header File: BookList.h #pragma once using namespace System; using namespace System::Collections; public ref class CBookList : public IList { private: int counter; array<Object ^> ^ objects; public: CBookList(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 void CopyTo(Array ^ ary, int index); virtual IEnumerator ^ GetEnumerator(); virtual property bool IsFixedSize { bool get() { return false; } } virtual property bool IsReadOnly { bool get() { return false; } } virtual int Add(Object ^ value); virtual void Insert(int index, Object ^ value); virtual property Object ^ default[int] { Object ^ get(int index) { return objects[index]; } void set(int index, Object ^ value) { objects[index] = value; } } virtual bool Contains(Object ^ value); virtual int IndexOf(Object ^ value); virtual void RemoveAt(int index); virtual void Remove(Object ^ value); virtual void Clear(); }; Source File: BookList.cpp #include "BookList.h" CBookList::CBookList(void) : counter(0), objects(gcnew array<Object ^>(5)) { } void CBookList::CopyTo(Array ^ ary, int index) { } IEnumerator ^ CBookList::GetEnumerator() { return nullptr; } int CBookList::Add(Object ^ value) { // Check whether there is still room in // the array to add a new item if (counter < objects->Length) { // Since there is room, put the new item to the end objects[counter] = value; // increase the number of items counter++; // Return the index of the item that was added return counter - 1; } // Since the item could not be added, return a negative index else return -1; } void CBookList::Insert(int index, Object ^ value) { } bool CBookList::Contains(Object ^ value) { for (int i = 0; i < Count; i++) if (objects[i] == value) return true; return false; } int CBookList::IndexOf(Object ^ value) { for (int i = 0; i < Count; i++) if (objects[i] == value) return i; return -1; } void CBookList::RemoveAt(int index) { if ((index >= 0) && (index < Count)) { for (int i = index; i < Count - 1; i++) objects[i] = objects[i + 1]; counter--; } } void CBookList::Remove(Object ^ value) { RemoveAt(IndexOf(value)); } void CBookList::Clear() { counter = 0; } Download: |
|
|||||||||||||||
|