·
Collections are introduced in .Net 1.0
·
Earlier we were using Array as collection to store multiple values of similar type. But
it has some drawbacks like:
·
Size of the Array is fixed, defined at compile
time. If we want to increase the array we need to create a new array with
updated (required) size and then copy the whole array into the newly created
array. .Net provides a method Array.Resize()
implemented in Array class, which does the same for us.
E.g.: int[] arr = new int[10]();
Array.Resize(ref arr,20);
·
We cannot directly add/ remove any array
element that is placed somewhere in the middle of the array. For that we need
to shift all remaining element accordingly.
·
To overcome these drawbacks, we use Syste.Collections.ArrayList. We can add an element
anywhere in ArrayList using arrayListObject.Insert(int
index, object value) and remove any element using either arrayListObject.Remove(object obj) or arrayListObject.RemoveAt(int index). ArrayList internally increases the
size as per requirement. By default it allocates memory for four (4) elements,
if we add fifth (5th) element then it doubles the size i.e. 8
elements. We can set the default capacity that ArrayList initially can have,
using ArrayList al = new ArrayList(10);
In this case ArrayList al will be created with initial capacity 10, and when we
will add the 11th element it will be increased to 20 elements.
·
ArrayList uses <key, value> pair for
each element, but the index is system defined, starting from 0. If we want to
have user defined keys for element then we use HashTable. It is same like ArrayList except it has user defined
keys. So to add any element in HashTable we need to pass two parameters like: hashTableObject.Add(object key, object
value). HashTable internally uses
HashCode to store the elements, that’s why when we access the elements through
loop, it does not returns the elements in a sequence as they were added. HashCodes
are internally generated using GetHashCode()method
of Object class which returns integer HashCode value.
·
Collections are not TypeSafe as they accepts
any type of element e.g. arrayListObject.Add(object
value), it will add any type of element, which can cause an issue. So we use
Generics. Generics are TypeSafe
collections, introduced in .Net 2.0
and come under System.Collections.Generic
namespace.
·
We can create any method or class generic by
adding <T> suffix.
E.g.: public
void add<T> (T parameter1, T parameter2){}
To call this function: add<int>(10,20);
public class
MyClass<T>
To create
object of this class: MyClass<int>
obj = new MyClass<int>();
Once
we create object of generic class with type <T>, we don’t need t add
<T> when we want to create generic method.
E.g.:
public void add(T parameter1, T
parameter2)
·
The generic version of ArrayList is List<T> which is similar to
ArrayList except, we need to pass type while creating the object. E.g.: List<int> li = new List<int>();
This will add only integer elements.
·
The generic version of HashTable is Dictionary<TKey, TValue> Though
HashTable and Dictionary are same but Dictionary doesn’t use HashCode to store
the element so we will get the elements as we added.
·
Dynamic is a data
type similar to Var introduced in .Net 4.0. Both are used to store any type of data, the only difference is var
identifies the datatype at compile time and dynamic identifies data type at
runtime. Var needs to be initialize at the time of declaration as it has to
identify the data type, whereas we don’t need to initialize the value of
dynamic variable.
·
Collections can be sorted by collectionObject.Sort() method. But it
supports only primitive data types like int, string etc. but in case of complex
data type like class, we need to explicitly write logic. Sort() method
internally calls compares two object, so to compare two complex object we need
to implement either IComparable or IComparer interface.
·
When we have to compare an object with the
current object, then we inherits IComparable<T>
interface and implements int CompareTo(T target) method.
E.g.:
suppose we have to compare two students by their ID’s then:
Public class Student :
IComparable<Student>
{
Public
int CompareTo(Student target){
Return this.ID – target.ID;
//returns 1 for positive, -1 for
negative and 0 for equal
}
}
Now
when we call studentCollection.Sort(), it
will sort collection by ID’s.
·
When we have to compare two objects in
different class, then we inherits IComparer<T>
interface and implements int Compare(T
source, T target) method.
E.g.:
suppose we have to compare two students by their ID’s but we don’t have edit
access to Student class then:
Public class CompareStudent :
IComparer<Student>
{
Public
int Compare(Student source, Student target){
Return source.ID – target.ID;
//returns 1 for positive, -1 for
negative and 0 for equal
}
}
Now
in this case, we need to pass the object of CompareStudent to Sort() method as:
CompareStudent obj = new
CompareStudent();
studentCollection.Sort(obj);
so this will sort collection by ID using Compare
method.