As stated already, the real role of the Collection<> class is to let you derive a class from it and implement some custom behaviors. To let you do this, the class is equipped with a property and some methods that are not inherited from ICollection<>. Because these are protected members, you must override them in your own class. You can start the class as follows: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; namespace CeilInn1 { [Serializable] public class RoomManagement<T> : Collection<T> { public RoomManagement() : base() { } } }
The Collection<> class has two constructors. The default is used to create an empty list. The other constructor uses the following syntax: public Collection(IList<T> list); This constructor allows you to create a list based on another existing list that is from a class that implements the IList<> interface. Here is an example of using this constructor: // References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
Button btnIntegers;
ListBox lbxNumbers;
Series<int> numbers;
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
btnNumbers = new Button();
btnNumbers.Text = "Numbers";
btnNumbers.Location = new System.Drawing.Point(12, 12);
btnNumbers.Click += new EventHandler(btnNumbersClicked);
btnIntegers = new Button();
btnIntegers.Text = "New Numbers";
btnIntegers.Width = 90;
btnIntegers.Location = new System.Drawing.Point(90, 12);
btnIntegers.Click += new EventHandler(btnIntegersClicked);
lbxNumbers = new ListBox();
lbxNumbers.Location = new System.Drawing.Point(40, 44);
Text = "Algebra";
Size = new System.Drawing.Size(200, 180);
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnNumbers);
Controls.Add(lbxNumbers);
Controls.Add(btnIntegers);
}
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
for(int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
private void btnIntegersClicked(object sender, EventArgs e)
{
Collection<int> integers = new Collection<int>(numbers);
lbxNumbers.Items.Clear();
for (int i = 0; i < integers.Count; i++)
lbxNumbers.Items.Add(integers[i]);
}
}
public class Series<T> : Collection<T>
{
}
On the other hand, if you had previously created a Collection<> object, to let you get it as an IList<>, the Collection<> class provides a property named Items that of type IList<>: protected IList<T> Items { get; } As you can see, Items is a protected property. This means that, to use it, you must first create a class that overrides it. In both cases, whether using the Collection(IList<T> list) constructor or the Items property to get a new list, once you have the new collection, you can use it as you see fit. For example, you can add new values to it. Here are examples: // References Needed: System.dll, // System.Drawing, // System.Windows.Form using System; using System.Windows.Forms; using System.Collections.Generic; using System.Collections.ObjectModel; public class Algebra : Form { Button btnNumbers; Button btnIntegers; ListBox lbxNumbers; Series<int> numbers; public Algebra() { InitializeComponent(); } private void InitializeComponent() { btnNumbers = new Button(); btnNumbers.Text = "Numbers"; btnNumbers.Location = new System.Drawing.Point(12, 12); btnNumbers.Click += new EventHandler(btnNumbersClicked); btnIntegers = new Button(); btnIntegers.Text = "New Numbers"; btnIntegers.Width = 90; btnIntegers.Location = new System.Drawing.Point(90, 12); btnIntegers.Click += new EventHandler(btnIntegersClicked); lbxNumbers = new ListBox(); lbxNumbers.Location = new System.Drawing.Point(40, 44); Text = "Algebra"; Size = new System.Drawing.Size(200, 180); StartPosition = FormStartPosition.CenterScreen; Controls.Add(btnNumbers); Controls.Add(lbxNumbers); Controls.Add(btnIntegers); } private void btnNumbersClicked(object sender, EventArgs e) { numbers = new Series<int>(); numbers.Add(2); numbers.Add(937); numbers.Add(49); numbers.Add(8); numbers.Add(64); for(int i = 0; i < numbers.Count; i++) lbxNumbers.Items.Add(numbers[i]); } private void btnIntegersClicked(object sender, EventArgs e) { Series<int> integers = (Series<int>)numbers.Items; integers.Add(1865); integers.Add(370); lbxNumbers.Items.Clear(); for (int i = 0; i < integers.Count; i++) lbxNumbers.Items.Add(integers[i]); } } public class Series<T> : Collection<T> { public IList<T> Items { get { return this; } } }
Of course, you can also perform all the other allowed operations on the new collection. using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn1
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
}
}
To let you customize the way an item should be inserted in a list, the Collection<> class provides the InsertItem() method. Its syntax is: protected virtual void InsertItem(int index, T item); This method takes two arguments: the item that will be inserted and the position it must occupy. Once again, the easisest implementation would consist of calling the parent's definition, which should be fine in a regular scenario. Here is an example: // References Needed: System.dll, // System.Drawing, // System.Windows.Form using System; using System.Windows.Forms; using System.Collections.Generic; using System.Collections.ObjectModel; public class Algebra : Form { Button btnNumbers; Button btnInsert; ListBox lbxNumbers; Series<int> numbers; public Algebra() { InitializeComponent(); } private void InitializeComponent() { btnNumbers = new Button(); btnNumbers.Text = "Numbers"; btnNumbers.Location = new System.Drawing.Point(12, 12); btnNumbers.Click += new EventHandler(btnNumbersClicked); btnInsert = new Button(); btnInsert.Text = "Insert"; btnInsert.Location = new System.Drawing.Point(90, 12); btnInsert.Click += new EventHandler(btnInsertClicked); lbxNumbers = new ListBox(); lbxNumbers.Location = new System.Drawing.Point(40, 44); Text = "Algebra"; Size = new System.Drawing.Size(200, 180); StartPosition = FormStartPosition.CenterScreen; Controls.Add(btnNumbers); Controls.Add(lbxNumbers); Controls.Add(btnInsert); } private void btnNumbersClicked(object sender, EventArgs e) { numbers = new Series<int>(); numbers.Add(2); numbers.Add(937); numbers.Add(49); numbers.Add(8); numbers.Add(64); for(int i = 0; i < numbers.Count; i++) lbxNumbers.Items.Add(numbers[i]); } private void btnInsertClicked(object sender, EventArgs e) { numbers.InsertItem(3, 10509); lbxNumbers.Items.Clear(); for (int i = 0; i < numbers.Count; i++) lbxNumbers.Items.Add(numbers[i]); } } public class Series<T> : Collection<T> { public new IList<T> Items { get { return this; } } public new void SetItem(int index, T item) { if (index < 0) return; else if (index > Count) return; else this[index] = item; // This too would work // base.SetItem(index, item); } public new void InsertItem(int index, T item) { base.InsertItem(index, item); } }
An alternative is to create your own implementation. For example, if the user passes an invalid index, the compiler would throw an ArgumentOutOfRangeException exception. One probable solution is to indicate to the compiler what to do in case of a problem. Here is an example: public new void InsertItem(int index, T item)
{
if( (index >= 0) && (index <= Count) )
base.InsertItem(index, item);
}
Of course, another solution is to call the ICollection<>.Insert() method. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; namespace CeilInn1 { [Serializable] public class RoomManagement<T> : Collection<T> { public RoomManagement() : base() { } public RoomManagement(IList<T> list) : base(list) { } public virtual new IList<T> Items { get { return this; } } public new void InsertItem(int index, T item) { if (index < 0) throw new ArgumentOutOfRangeException("The value you provided " + "for the index is not valid"); else if ((index >= 0) && (index <= Count)) base.InsertItem(index, item); else // If the index is higher than Count, simply add the item (at the end of the list) this.Add(item); } } }
The Collection<> class implements the ICollection interface. This allows you to access an item using its index. Besides the ability to specify the value an item based on its index, the Collection<> class provides the SetItem() method that makes it possible to change an item. Its syntax is: protected virtual void SetItem(int index, T item); The item argument holds the value that will be assigned to the item at the index position. When overriding this method, the simplest implementation would consist of calling the same method of the parent class. Here is an example: // References Needed: System.dll, // System.Drawing, // System.Windows.Form using System; using System.Windows.Forms; using System.Collections.Generic; using System.Collections.ObjectModel; public class Algebra : Form { Button btnNumbers; Button btnChange; ListBox lbxNumbers; Series<int> numbers; public Algebra() { InitializeComponent(); } private void InitializeComponent() { btnNumbers = new Button(); btnNumbers.Text = "Numbers"; btnNumbers.Location = new System.Drawing.Point(12, 12); btnNumbers.Click += new EventHandler(btnNumbersClicked); btnChange = new Button(); btnChange.Text = "New Numbers"; btnChange.Width = 90; btnChange.Location = new System.Drawing.Point(90, 12); btnChange.Click += new EventHandler(btnChangeClicked); lbxNumbers = new ListBox(); lbxNumbers.Location = new System.Drawing.Point(40, 44); Text = "Algebra"; Size = new System.Drawing.Size(200, 180); StartPosition = FormStartPosition.CenterScreen; Controls.Add(btnNumbers); Controls.Add(lbxNumbers); Controls.Add(btnChange); } private void btnNumbersClicked(object sender, EventArgs e) { numbers = new Series<int>(); numbers.Add(2); numbers.Add(937); numbers.Add(49); numbers.Add(8); numbers.Add(64); for(int i = 0; i < numbers.Count; i++) lbxNumbers.Items.Add(numbers[i]); } private void btnChangeClicked(object sender, EventArgs e) { numbers.SetItem(2, 13579); lbxNumbers.Items.Clear(); for (int i = 0; i < numbers.Count; i++) lbxNumbers.Items.Add(numbers[i]); } } public class Series<T> : Collection<T> { public new IList<T> Items { get { return this; } } public new void SetItem(int index, T item) { base.SetItem(index, item); } }
Otherwise, when defining this method, you must decide what to do in case of this or that. For example, what should the compiler do if the index is negative? What if the passed index is higher than the total number of items in the collection. In this case, by default, the compiler would throw an IndexOutRangeException exception. One alternative is to ignore the new value if the index is out of range. Here is an example of implementing: // References Needed: System.dll, // System.Drawing, // System.Windows.Form using System; using System.Windows.Forms; using System.Collections.Generic; using System.Collections.ObjectModel; public class Algebra : Form { Button btnNumbers; Button btnChange; ListBox lbxNumbers; Series<int> numbers; . . . private void btnChangeClicked(object sender, EventArgs e) { numbers.SetItem(12, 13579); lbxNumbers.Items.Clear(); for (int i = 0; i < numbers.Count; i++) lbxNumbers.Items.Add(numbers[i]); } } public class Series<T> : Collection<T> { public new IList<T> Items { get { return this; } } public new void SetItem(int index, T item) { if (index < 0) return; else if (index > Count) return; else this[index] = item; // This too would work // base.SetItem(index, item); } } Another alternative is to add the item as the last in the list. using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
public new void InsertItem(int index, T item)
{
if (index < 0)
throw new ArgumentOutOfRangeException("The value you provided " +
"for the index is not valid");
else if ((index >= 0) && (index <= Count))
base.InsertItem(index, item);
else
// If the index is higher than Count, simply add the item (at the end of the list)
this.Add(item);
}
public new void SetItem(int index, T item)
{
if (index < 0)
return;
else if (index > Count)
return;
else
base.SetItem(index, item);
}
}
}
To let you delete an item from its list, the Collection<> class provides the RemoveItem() method. Its syntax is: protected virtual void RemoveItem(int index); This method takes as argument the index of the item to be removed. Once again, a simply implementation would consist of calling the base method. Here is an example; public new void RemoveItem(int index)
{
base.RemoveItem(index);
}
An alternative that produces the same effect is to call the ICollection<>.RemoveAt() method. Here is an example: public new void RemoveItem(int index)
{
base.RemoveAt(index);
}
Otherwise, when implementing this method, you will decide what to do if the index is negative or is higher than the total number of items in the list. Also, you can specify what other actions the compiler should take when an item is being deleted. using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
public new void InsertItem(int index, T item)
{
if (index < 0)
throw new ArgumentOutOfRangeException("The value you provided " +
"for the index is not valid");
else if ((index >= 0) && (index <= Count))
base.InsertItem(index, item);
else
// If the index is higher than Count, simply add the item (at the end of the list)
this.Add(item);
}
public new void SetItem(int index, T item)
{
if (index < 0)
return;
else if (index > Count)
return;
else
base.SetItem(index, item);
}
public new void RemoveItem(int index)
{
if (index < 0)
return;
else if (index > Count)
return;
else
base.RemoveItem(index);
}
}
}
Because the Collection<> class implements the ICollection interface, it inherits the Clear() method. To let you create a custom technique to delete all items from a class, the Collection class is equipped with the protected ClearItems() method. Its syntax is: protected virtual void ClearItems(); When overriding this method, if you don't have any particular way you want to delete items, you can simply call the Clear() method. Otherwise, define the method as you wish. |
|
|||||||||||||||
|