Apr 10, 2009

Generics are similar to Templates in C++, where it can process something independent of type. It was available since C# 2.0.

// ex from Learning C# 3.0 O'Reilly
class Stack<T>
Stack<Employee> = new Stack<Employee>

Indexer

allows a class to be indexed, like an array, with [i].

// inside a class 
public TYPE this[int index] {
	get { ... }
	set { ... }
}

Example

class MyClass {
    ...
    string[] _my_items;
    public string this[int index] {
        get { if index>=0 && index < _myItems.Length return _my_items[index];}
        set { if index>=0 && index < _myItems.Length_my_items[index]= value; }
    }
}
...
MyClass obj = new MyClass;

Generic Collection Interfaces

Requirements:

using System.Collections.Generic;

IEnumerable<T>

Example:

// my own
public class Word : IEnumerable <String>
{
    string[] _synonyms; // init later in constructor
    public IEnumerator<string> GetEnumerator()
    {
        foreach (string s in _synonyms)
        {
            yield return s;
        }

    }
    // this is a mandatory method. All it needs to do is to throw exception
    System.Collections.IEnumerator
    System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

//
Word word = new Word("precious");
foreach (string synonym in word) {...}

List<T>

Example : string

List<string> stringlist =  new List<string>();
stringlist.Add("Apple");
stringlist.Add("Banana");
stringlist.Sort( );
for(int i = 0; i < stringlist.Count; i++)
   		Console.WriteLine(stringlist[i]);

Example: class

// Learning C# 3.0 OReilly - some parts
public class Employee
{   ...
    private int empID;
    public override string ToString() { return empID.ToString();}
}
...
List<Employee> empList = new List<Employee>();
...
empList.add(new Employee(34));
empList.add(new Employee(9));
empList.add(new Employee(42));
Console.WriteLine(empList.Capacity));
...

initializing

List<int> numbers = new List<int>();  // empty
var numbers = new List<int>()       // empty 
var numbers = new List<int> { 123, 99, 42 }; // with 3 elements

Property

l.Capacity: property that gets/sets # of elements
l.Count: property that gets # of elements
l[index]: get/set item at index. Careful not to go out of range
    on non-C#, it uses .Items property.

common methods

l.Add(value)
l.Clear() : removes all elements
l.Insert(value)
l.Remove(value): remove 1st occurrence of value
l.RemoveAt(index)
l.TrimExcess() : sets capacity to actual elements in List, i.e. remove empty 

search, sort

l.BinarySearch()
l.Contains(value): 
l.Exists()
l.Find()
l.FindAll()
l.IndexOf(value): index of first occurrence 
l.LastIndexOf(value)
l.Sort(): see sorting below
l.Reverse()

others

l.CopyTo(): converts to an array
l.ToArray() converts to new array
l.GetEnumerator(): returns enumerator to iterate

Sorting

l.Sort() and l.Reverse() for generic list to implement IComparable * IComparable has method CompareTo(TYPE rhs) to implement.

// Learning C# 3.0 OReilly - some parts

public class Employee : IComparable<Employee>
{   ...
    private int empID;

    public bool Equals(Employee other) { 
        if this.empID == other.empID return true;
        return false;
    }
    public int CompareTo(Employee right) {
        return this.empID.CompareTo(right.empID);
        // since empID is int, it already has a built-in CompareTo.
        // Thus, it can just use its CompareTo
        // others must implement own... no detail in the book
    }
}
...
List<Employee> empList = new List<Employee>();
...
empList.Sort();

Implement own IComparer * instead of built-in QuickSort, one can use own. see Learning C# 3.0 p314-319 * can sort via different parameters, ie via id # or via names, etc

Example of initializing

// from Learning C# 3.0 O'Reillys
public class Book {
    public string Title;
    public string Author;
    public string Publisher;
    public int PublicationYear;
}

List<Book> bookList = new List<Book>
{
new Book{ Title = "Learning C# 3.0",
    Author= "Jesse Liberty",
    Publisher="O'Reilly",
    iPublicationYear=2008 } ,
new Book{ Title = "Programming C# ",
    Author= "Jesse Liberty",
    Publisher="O'Reilly",
    iPublicationYear=2005 } 
}

Queue<T>

Queue<Int32> intQueue = new Queue<Int32>();
intQueue.Enqueue(42);
printAll(intQueue);

...
// alternative to foreach, we pass IEnumerable and use MoveNext().
public static void printAll(IEnumerable<Int32> data){
    IEnumerator<Int32> enumerator = data.GetEnumerator();
    while (enumerator.MoveNext()) { Console.Write(enumerator.Current); }
}

Methods

q.Dequeue()
q.Enqueue()
q.Peek()    // returns 1st item without removing it

q.Count
q.Clear()
q.Contains()
q.CopyTo()
q.ToArray()

q.GetEnumerator();// 

Systems.Collections.Queue

Stack<T>

Stack<Int32> s = new Stack<Int32>();

Methods

s.Pop()
s.Push()

s.Count
s.Clear()
s.Contains()
s.CopyTo()
s.ToArray()

s.GetEnumerator();// 

Dictionary<K,V>

Example

Dictionary<string, string> d = new Dictionary<string,string>();
d.Add("Name","Dan");
d.Add("State","California");

d["State"] // ===> "California"

Methods

d[key], implemented using Item property
d.Keys  : list of keys
d.Values    : list of values
d.Add(key,value)
d.Remove(key)

d.Count
d.Clear()
d.ContainsKey()
d.ContainsValue()
d.CopyTo()
d.ToArray()

d.GetEnumerator();// 

Others

System.Collections.ArrayList: Deprecated by List<T>
System.Collections.Hashtable
Hashtable t = new Hashtable(size);
.Add(key,value)
	if key already exists, it is NOT OVERWRITTEN. use []/item instead.
		[
		hash.Add("c","cherry");
		hash.Add("c","strange");  // "ArgumentException" will occur!
		]
.Remove(key)
.Count
<table> [ key ] (aka .Item prop) -> sets/returns value. If key exists, it is overwritten
Iterating using foreach
	Must set DictionaryEntry class which contains both key & value::
		foreach (DictionaryEntry item in hash) Debug.WriteLine(item.Value);
	DictionaryEntry.Key
	DictionaryEntry.Value 

.Keys, .Values : ICollection of keys/values. One can copy it to array using CopyTo
	.Keys.CopyTo(Array, int index)
	.Keys.Count: gets count size of key. Prob better to just use hashtable.Count instead.
	.Values.CopyTo ( ..)
	.Values.Count: # of values. Prob better to just use hashtable.Count instead.
	Example: 
	[
		string[] arr = new string[myhash.Count];
		myhash.Values.CopyTo(arr,0);
		foreach (string val in arr) {
			Debug.WriteLine(val);
	]
.ContainsKey(key): returns true if such key exists
.ContainsValue(value):
Systems.Collections.SortedList # uses sort & binary search
Systems.Collections.Specialized.StringCollection
Systems.Collections.Stack
Systems.Collections.BitArray

Event Methods

public event EventHandler changed;