using System; // Gen has two type arguments and both have // a where clause. class Gen<T, V> where T : class where V : struct { T ob1; V ob2; public Gen(T t, V v) { ob1 = t; ob2 = v; } } class Test { public static void Main() { Gen<string, int> obj = new Gen<string, int>("test", 11); // The next line is wrong because bool is not // a reference type. // Gen<bool, int> obj = new Gen<bool, int>(true, 11); } }
Generics
Generic Queue
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Collections.ObjectModel; using System.Runtime.Serialization; public class Customer : System.IComparable { private int _id; private string _name; private string _rating; private static SortOrder _order; public enum SortOrder { Ascending = 0, Descending = 1 } public Customer(int id, string name) : this(id, name, "Other") { } public Customer(int id, string name, string rating) { this._id = id; this._name = name; this._rating = rating; } public int Id { get { return this._id; } set { this._id = value; } } public string Name { get { return this._name; } set { this._name = value; } } public string Rating { get { return this._rating; } set { this._rating = value; } } public static SortOrder Order { get { return _order; } set { _order = value; } } public override bool Equals(Object obj) { bool retVal = false; if (obj != null) { Customer custObj = (Customer)obj; if ((custObj.Id == this.Id) && (custObj.Name.Equals(this.Name) && (custObj.Rating.Equals(this.Rating)))) retVal = true; } return retVal; } public override string ToString() { return this._id + ": " + this._name; } public int CompareTo(Object obj) { switch (_order) { case SortOrder.Ascending: return this.Name.CompareTo(((Customer)obj).Name); case SortOrder.Descending: return (((Customer)obj).Name).CompareTo(this.Name); default: return this.Name.CompareTo(((Customer)obj).Name); } } } class Program { public static void Main(){ Queue<Customer> custQueue = new Queue<Customer>(100); custQueue.Enqueue(new Customer(99, "H", "P")); custQueue.Enqueue(new Customer(77, "B", "G")); custQueue.Enqueue(new Customer(55, "B", "S")); custQueue.Enqueue(new Customer(88, "B", "P")); Customer tmpCust = custQueue.Dequeue(); Console.Out.WriteLine("Dequeued: {0}", tmpCust); foreach (Customer cust in custQueue) Console.Out.WriteLine("Queue Item: {0}", cust); tmpCust = custQueue.Peek(); Console.Out.WriteLine("Queue Peek: {0}", tmpCust); custQueue.Enqueue(new Customer(88, "B", "P")); foreach (Customer cust in custQueue) Console.Out.WriteLine("Queue Item: {0}", cust); } }
Implement generic IEnumerable and IEnumerator
using System; using System.Threading; using System.Collections; using System.Collections.Generic; public class MyEnumerable<T> : IEnumerable<T> { public MyEnumerable( T[] items ) { this.items = items; } public IEnumerator<T> GetEnumerator() { return new NestedEnumerator( this ); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } // The enumerator definition. class NestedEnumerator : IEnumerator<T> { public NestedEnumerator( MyEnumerable<T> coll ) { Monitor.Enter( coll.items.SyncRoot ); this.index = -1; this.coll = coll; } public T Current { get { return current; } } object IEnumerator.Current { get { return Current; } } public bool MoveNext() { if( ++index >= coll.items.Length ) { return false; } else { current = coll.items[index]; return true; } } public void Reset() { current = default(T); index = 0; } public void Dispose() { try { current = default(T); index = coll.items.Length; } finally { Monitor.Exit( coll.items.SyncRoot ); } } private MyEnumerable<T> coll; private T current; private int index; } private T[] items; } public class EntryPoint { static void Main() { MyEnumerable<int> integers = new MyEnumerable<int>( new int[] {1, 2, 3, 4} ); foreach( int n in integers ) { Console.WriteLine( n ); } } }
Implement generic IEnumerable
using System; using System.Collections; using System.Collections.Generic; public class MyColl<T> : IEnumerable<T> { private T[] items; public MyColl( T[] items ) { this.items = items; } public IEnumerator<T> GetEnumerator() { foreach( T item in items ) { yield return item; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class Test { static void Main() { MyColl<int> integers = new MyColl<int>( new int[] {1, 2, 3, 4} ); foreach( int n in integers ) { Console.WriteLine( n ); } } }
Implements IComparable
using System; using System.Collections.Generic; public class Book : IComparable<Book> { private string name; private int circulation; private class AscendingCirculationComparer : IComparer<Book> { public int Compare(Book x, Book y) { if (x == null && y == null) return 0; else if (x == null) return -1; else if (y == null) return 1; if (x == y) return 0; return x.circulation - y.circulation; } } public Book(string name, int circulation) { this.name = name; this.circulation = circulation; } public static IComparer<Book> CirculationSorter { get { return new AscendingCirculationComparer(); } } public override string ToString() { return string.Format("{0}: Circulation = {1}", name, circulation); } public int CompareTo(Book other) { if (other == null) return 1; if (other == this) return 0; return string.Compare(this.name, other.name, true); } } public class MainClass { public static void Main() { List<Book> Books = new List<Book>(); Books.Add(new Book("E", 1)); Books.Add(new Book("T", 5)); Books.Add(new Book("G", 2)); Books.Add(new Book("S", 8)); Books.Add(new Book("H", 5)); foreach (Book n in Books) { Console.WriteLine(" " + n); } Books.Sort(); foreach (Book n in Books) { Console.WriteLine(" " + n); } Books.Sort(Book.CirculationSorter); foreach (Book n in Books) { Console.WriteLine(" " + n); } } }
Reference for Generic Types
using System; public class Starter { public static void Main() { MyClass<int> obj = new MyClass<int>(); obj.MethodA(); } } class MyClass<T> { public T MethodA() { T var = default(T); Console.WriteLine(this.GetType().ToString()); return var; } }
A generic Point structure.
using System; using System.Collections.Generic; using System.Text; public struct Point<T> { private T xPos; private T yPos; public Point(T xVal, T yVal) { xPos = xVal; yPos = yVal; } public T X { get { return xPos; } set { xPos = value; } } public T Y { get { return yPos; } set { yPos = value; } } public override string ToString() { return string.Format("[{0}, {1}]", xPos, yPos); } public void ResetPoint() { xPos = default(T); yPos = default(T); } }