As mentioned above, to create a collection, you can derive it from the IList interface. Here is an example: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
public BookList()
{
}
}
This System.Collections.IList interface is declared as follows: public interface IList : ICollection, IEnumerable This System.Collections.Generic.IList interface is declared as follows: public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable This means that the IList interface exdends both the ICollection and the IEnumerable interfaces. This also implies that you must implement the members of these parent interfaces. In other words, you must implement the Count property, the SyncRoot property, the IsSynchronized property, and the CopyTo() method of the ICollection interface. From what we learned with ICollection, here are examples of implementing these members for the System.Collections.IList interface: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
private int counter;
private object[] objs;
public BookList()
{
counter = 0;
objs = new array[5];
}
public virtual int Count
{
get { return items; }
}
public virtual bool IsSynchronized
{
get { return false; }
}
public virtual object SyncRoot
{
get { return this; }
}
public virtual void CopyTo(Array ary, int index)
{
}
}
You must also implement the System.Collections.GetEnumerator() (or the System.Collections.Generic.GetEnumerator()) method of the System.Collections.IEnumerable (or of the System.Collections.Generic.IEnumerable) interface. If you do not have time to completely implement it, you can simply return null. Here is an example for the System.Collections.IList interface: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public IEnumerator GetEnumerator()
{
return null;
}
}
In the next sections, we will see how to add values to a list of a database. As you add or insert values in a list, the Count property grows. If your collection is array-based, when you start it, you specify the number of values that the list will contain. In theory, you cannot add new values beyond that number. In reality, you can increase the size of an array and then add a new item. If your collection is a linked list, you are also not confined to the laws of space (unless your computer runs out of memory). If you create a list whose number of values must be constant, the user cannot add values beyond the maximum allowed number. Therefore, before adding a value, you can first check whether the collection has a fixed size or not. To give you this information, the IList interface is equipped with a Boolean read-only property named IsFxedSize. This property simply lets the user know whether the collection has a fixed number of items. Here is an example of implementing this property for the System.Collections.IList interface: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public virtual bool IsFixedSize
{
get { return false; }
}
}
Most databases are meant to receive new values. If you want, you can create a list that cannot receive new values. To support this, the IList interface is equipped with the Boolean IsReadOnly property. If a list is read-only, it would prevent the clients from adding items to it. Here is an example of implementing the IsReadOnly property for the System.Collections.IList interface: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public virtual bool IsReadOnly
{
get { return false; }
}
}
As it should be obvious, the primary operation to perform on a list is to populate it with at least one value. To support this, the System.Collections.IList interface is equipped with a method named Add. Its syntax is: int Add(object value); This method takes one argument as the value to add to the list. If your collection is an array, you can first check that there is still enough room in the list to add a new item. In reality, this is never an issue with the System.Collections.IList interface:
If the method succeeds with the addition, it returns the position where the value was added in the list. This is usually the last position in the list. Here is an example: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public virtual int 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[items] = value;
// increase the number of items
objects++;
// 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;
}
}
When you call the System.Collections.IList.Add() method, it adds the new value to the end of the list. Sometimes, you will want the new value to be insert somewhere inside the list. To support this operation, both the System.Collections.IList and the System.Collections.Generic.IList interfaces provide a method named Insert. The syntax of the System.Collections.IList.Insert() method is: void Insert(int index, object value); The syntax of the System.Collections.Generic.IList.Insert() method is: void Insert(int index, T value); This method takes two arguments. The second argument is the value that will be inserted into the list. The argument must hold a valid value. Because this method takes an Object object, if your collection is using a different type of value, you may have to cast it to Object. The first argument is the index of the item that will precede the new one. As mentioned for the System.Collections.IList. Add() method, there are a few things you should know about this operation's success or lack of it:
While using a list, various operations require that you know the object you are currently accessing. To provide this operation, you must create an indexed property. This property should take an index and return the type of object that makes up the list. Here is an example: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public virtual object this[int index]
{
get { return objects[index]; }
set
{
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 foreach, you must appropriately implement the IEnumerable.GetEnumerator() method.
One of the most valuables features of the C# is the ability to use the foreach 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: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public bool 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: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public int 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: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public void RemoveAt(int index)
{
if ((index >= 0) && (index < Count))
{
for (int i = index; i < Count - 1; i++)
objects[i] = objects[i + 1];
items--;
}
}
}
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: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
. . . No Change
public virtual void 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: using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
/// <summary>
/// Summary description for BookList
/// </summary>
public class BookList : IList
{
private int counter;
private object[] objects;
public BookList()
{
counter = 0;
objects = new object[5];
}
public virtual int Count
{
get { return counter; }
}
public virtual bool IsSynchronized
{
get { return false; }
}
public virtual object SyncRoot
{
get { return this; }
}
public virtual void CopyTo(Array ary, int index)
{
}
public IEnumerator GetEnumerator()
{
return null;
}
public virtual bool IsFixedSize
{
get { return false; }
}
public virtual bool IsReadOnly
{
get { return false; }
}
public virtual int 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;
}
public virtual void Insert(int index, object value)
{
}
public virtual object this[int index]
{
get { return objects[index]; }
set
{
objects[index] = value;
}
}
public virtual bool Contains(object value)
{
for (int i = 0; i < Count; i++)
if (objects[i] == value)
return true;
return false;
}
public virtual int IndexOf(object value)
{
for (int i = 0; i < Count; i++)
if (objects[i] == value)
return i;
return -1;
}
public virtual void RemoveAt(int index)
{
if ((index >= 0) && (index < Count))
{
for (int i = index; i < Count - 1; i++)
objects[i] = objects[i + 1];
counter--;
}
}
public virtual void Remove(Object value)
{
RemoveAt(IndexOf(value));
}
public virtual void Clear()
{
counter = 0;
}
}
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||