Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

Unit 5: Delegates, Collection classes

In C#, delegates are first-class objects, fully supported by the language. Technically, a
delegate is a reference type used to encapsulate a method with a specific signature and
return type. You can encapsulate any matching method in that delegate. (In C++ and
many other languages, you can accomplish this requirement with function pointers and
pointers to member functions. Unlike function pointers, delegates are object-oriented
and type-safe.)

A delegate is created with the delegate keyword, followed by a return type and the
signature of the methods that can be delegated to it, as in the following:

public delegate int WhichIsFirst(object obj1, object obj2);

This declaration defines a delegate named WhichIsFirst, which will encapsulate any
method that takes two objects as parameters and returns an int.

Once the delegate is defined, you can encapsulate a member method with that delegate
by
instantiating the delegate, i.e., passing in a method that matches the return type and
signature.

The best use of delegate is to use as event.

Internally a delegate declaration defines a class which is the derived class


of System.Delegate.

Syntax:-delegate <return type> <delegate-name> <parameter list>

Eg.public delegate int MyDelegate (string s);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace delegateeg
{
public delegate int DelegatSample(int a,int b);

public class Sampleclass


{
public int Add(int x, int y)
{
return x + y;
}
public int Sub(int x, int y)
{
return x - y;
}
class Program
{
static void Main(string[] args)
{

Sampleclass sc = new Sampleclass();

DelegatSample delgate1 = sc.Add;


int i = delgate1(10, 20);
Console.WriteLine(i);
DelegatSample delgate2 = sc.Sub;
int j = delgate2(20, 10);
Console.WriteLine(j);
Console.ReadLine();

}
}
}
}

Types of Delegates

There are three types of delegates that can be used in C#.

• Single Delegate
• Multicast Delegate
• Generic Delegate

Single Delegate

Single delegate can be used to invoke a single method.

• Multicast Delegate

Delegate objects can be composed using the "+" operator. A composed delegate calls
the two delegates it was composed from. Only delegates of the same type can be
composed. The "-" operator can be used to remove a component delegate from a
composed delegate.

public delegate void MultiDelegate(int a,int b);


public class Sampleclass
{
public static void Add(int x, int y)
{
Console.WriteLine("Addition Value: "+(x + y));
}
public static void Sub(int x, int y)
{
Console.WriteLine("Subtraction Value: " + (x - y));
}
public static void Mul(int x, int y)
{
Console.WriteLine("Multiply Value: " + (x * y));
}
}
class Program
{
static void Main(string[] args)
{
Sampleclass sc=new Sampleclass();
MultiDelegate del = Sampleclass.Add;
del += Sampleclass.Sub;
del += Sampleclass.Mul;
del(10, 5);
Console.ReadLine();
}
}

Generic Delegate

A generic delegate can be defined the same way as a delegate but using generic type
parameters or return type. The generic type must be specified when you set a target
method.

public delegate T add<T> (T param1, T param2); // generic delegate

using System;
using System. Collections. Generic;
using System.Linq;
using System.Text;

public delegate T add<T> (T param1, T param2);

namespace genericdelegateeg
{
class Program
{
static void Main(string[] args)
{

add<int> sum = Sum;

Console.WriteLine(sum(10, 20));

add<string> conct = Concat;

Console.WriteLine(conct("Hello","World!!"));
Console.ReadLine();
}

public static int Sum(int val1, int val2)


{
return val1 + val2;
}

public static string Concat(string str1, string str2)


{
return str1 + str2;
}
}
}

C# - Anonymous Method
As the name suggests, an anonymous method is a method without a name.
Anonymous methods in C# can be defined using the delegate keyword and can be
assigned to a variable of delegate type.

using System;
using System.Collections. Generic;
using System.Linq;
using System.Text;

namespace anonymouseg
{

public delegate void Print(int value);


class Program
{
static void Main(string[] args)
{
Print print = delegate(int val)
{
Console.WriteLine("Inside Anonymous method. Value: {0}", val);
Console.ReadLine();
};

print(100);
}
}
}
❖ Collections
The Non-Generic Collection Classes

Non-generic
Collections Usage

ArrayList ArrayList stores objects of any type like an array. However, there is no
need to specify the size of the ArrayList like with an array as it grows
automatically.

SortedList SortedList stores key and value pairs. It automatically arranges elements
in ascending order of key by default. C# includes both, generic and non-
generic SortedList collection.

Stack Stack stores the values in LIFO style (Last In First Out). It provides a
Push() method to add a value and Pop() & Peek() methods to retrieve
values. C# includes both, generic and non-generic Stack.

Queue Queue stores the values in FIFO style (First In First Out). It keeps the
order in which the values were added. It provides an Enqueue() method to
add values and a Dequeue() method to retrieve values from the collection.
C# includes generic and non-generic Queue.

Hashtable Hashtable stores key and value pairs. It retrieves the values by comparing
the hash value of the keys.

Now that you are familiar with the non-generic collection interfaces, we can examine the
standard classes that implement them. With the exception of BitArray, described later,
the
non-generic collection classes are summarized here:

ArrayList - A dynamic array. This is an array that can grow as needed.


Hashtable - A hash table for key/value pairs.
Queue - A first-in, first-out list.
Stack- A first-in, last-out list.

ArrayList

ArrayList implements the IList interface using an array whose size is dynamically
increased as required. In this article I explain how to create the ArrayList and the
various methods and properties of the ArrayList.

Important Properties and methods of ArrayList:

Property Description

Capacity Gets or sets the number of elements that the ArrayList can
contain.

Count Gets the number of elements actually contained in the ArrayList.

IsFixedSize Gets a value indicating whether the ArrayList has a fixed size.

IsReadOnly Gets a value indicating whether the ArrayList is read-only.

Item Gets or sets the element at the specified index.

Method Description

Add() Add() method adds single elements at the end of ArrayList.

Insert() Insert() method insert a single elements at the specified index in


ArrayList.

Remove() Remove() method removes the specified element from the


ArrayList.

RemoveAt() Removes the element at the specified index from the ArrayList.

Sort() Sorts entire elements of the ArrayList.

Reverse() Reverses the order of the elements in the entire ArrayList.


Property Description

Contains Checks whether specified element exists in the ArrayList or not.


Returns true if exists otherwise false.

namespace ArrayList1
{
class Program
{
static void Main(string[] args)
{
ArrayList arr = new ArrayList();
arr.Add("Sunday");
arr.Add("Monday");
arr.Add("Tuesday");
arr.Add("Wednesday");
arr.Add("Thusday");
arr.Add("Friday");
arr.Add("Saturday");
Console.WriteLine("The elements of the ArrayList are:");
foreach (object obj in arr)
{
Console.WriteLine(obj);
}
}
}
}
Hashtable
The Hashtable class represents a collection of key-and-value pairs that are organized
based on the hash code of the key. It uses the key to access the elements in the
collection.
A hash table is used when you need to access elements by using key, and you can
identify a useful key value. Each item in the hash table has a key/value pair. The key is
used to access the items in the collection.

using System;
using System.Collections;

namespace CollectionsApplication {

class Program {

static void Main(string[] args) {


Hashtable ht = new Hashtable();

ht.Add("001", "Zara Ali");


ht.Add("002", "Abida Rehman");
ht.Add("003", "Joe Holzner");
ht.Add("004", "Mausam Benazir Nur");
ht.Add("005", "M. Amlan");
ht.Add("006", "M. Arif");
ht.Add("007", "Ritesh Saikia");

if (ht.ContainsValue("Nuha Ali")) {
Console.WriteLine("This student name is already in the list");
} else {
ht.Add("008", "Nuha Ali");
}
// Get a collection of the keys.
ICollection key = ht.Keys;

foreach (string k in key) {


Console.WriteLine(k + ": " + ht[k]);
}
Console.ReadKey();
}
}
}

Stack

It represents a last-in, first out collection of object. It is used when you need a last-in,
first-out access of items. When you add an item in the list, it is called pushing the item
and when you remove it, it is called popping the item.

Property Usage

Count Returns the total count of elements in the Stack.

Method Usage

Push Inserts an item at the top of the stack.

Peek Returns the top item from the stack.

Pop Removes and returns items from the top of the stack.

Contains Checks whether an item exists in the stack or not.

Clear Removes all items from the stack.

using System;
using System.Collections;
class Program
{
static Stack GetStack()
{
Stack stack = new Stack();
stack.Push(100);
stack.Push(1000);
stack.Push(10000);
return stack;
}

static void Main()


{
var stack = GetStack();
Console.WriteLine("--- Stack contents ---");
foreach (int i in stack)
{
Console.WriteLine(i);
}
}
}
Queue
It represents a first-in, first out collection of object. It is used when you need a first-in,
first-out access of items. When you add an item in the list, it is called enqueue, and
when you remove an item, it is called deque.

Property Usage

Count Returns the total count of elements in the Queue.

Method Usage

Enqueue Adds an item into the queue.


Property Usage

Dequeue Removes and returns an item from the beginning of the queue.

Peek Returns an first item from the queue

Contains Checks whether an item is in the queue or not

Clear Removes all the items from the queue.

TrimToSize Sets the capacity of the queue to the actual number of items in the queue.

using System;
using System.Collections;
class Program
{
static void Main()
{
// New Queue of integers.
Queue q = new Queue ();

q.Enqueue(5); // Add 5 to the end of the Queue.


q.Enqueue(10); // Then add 10. 5 is at the start.
q.Enqueue(15); // Then add 15.
q.Enqueue(20); // Then add 20.

Console.WriteLine("--- Queue contents ---");


foreach (int i in q)
{
Console.WriteLine(i);
}
}
}
❖ Generic Collection classes

Generic Collections Description

List<T> Generic List<T> contains elements of specified type. It grows


automatically as you add elements in it.

Dictionary<TKey,TValue> Dictionary<TKey,TValue> contains key-value pairs.

SortedList<TKey,TValue> SortedList stores key and value pairs. It automatically adds


the elements in ascending order of key by default.

Queue<T> Queue<T> stores the values in FIFO style (First In First Out).
It keeps the order in which the values were added. It provides
an Enqueue() method to add values and a Dequeue() method
to retrieve values from the collection.

Stack<T> Stack<T> stores the values as LIFO (Last In First Out). It


provides a Push() method to add a value and Pop() & Peek()
methods to retrieve values.

Hashset<T> Hashset<T> contains non-duplicate elements. It eliminates


duplicate elements.

C# List<T> -
C# List<T> class is used to store and fetch elements. It can have duplicate elements. It
is found in System.Collections.Generic namespace.

using System;
using System.Collections.Generic;

public class ListExample


{
public static void Main(string[] args)
{
// Create a list of strings
List<string> names = new List<string>();
names.Add("Sonoo Jaiswal");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");

// Iterate list element using foreach loop


foreach (var name in names)
{
Console.WriteLine(name);
}
}
}

C# HashSet<T>

C# HashSet class can be used to store, remove or view elements. It does not store
duplicate elements. It is suggested to use HashSet class if you have to store only unique
elements. It is found in System.Collections.Generic namespace.

using System;
using System.Collections.Generic;

public class HashSetExample


{
public static void Main(string[] args)
{
// Create a set of strings
HashSet<string> names = new HashSet<string>();
names.Add("Sonoo");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
names.Add("Ankit");//will not be added

// Iterate HashSet elements using foreach loop


foreach (var name in names)
{
Console.WriteLine(name);
}
}
}

C# SortedSet<T>

C# SortedSet class can be used to store, remove or view elements. It maintains


ascending order and does not store duplicate elements. It is suggested to use SortedSet
class if you have to store unique elements and maintain ascending order. It is found in
System.Collections.Generic namespace.

using System;
using System.Collections.Generic;

public class SortedSetExample


{
public static void Main(string[] args)
{
// Create a set of strings
SortedSet<string> names = new SortedSet<string>();
names.Add("Sonoo");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
names.Add("Ankit");//will not be added
// Iterate SortedSet elements using foreach loop
foreach (var name in names)
{
Console.WriteLine(name);
}
}
}

C# Stack<T>

C# Stack<T> class is used to push and pop elements. It uses the concept of Stack that
arranges elements in LIFO (Last In First Out) order. It can have duplicate elements. It is
found in System.Collections.Generic namespace.
using System;
using System.Collections.Generic;

public class StackExample


{
public static void Main(string[] args)
{
Stack<string> names = new Stack<string>();
names.Push("Sonoo");
names.Push("Peter");
names.Push("James");
names.Push("Ratan");
names.Push("Irfan");

foreach (string name in names)


{
Console.WriteLine(name);
}
Console.WriteLine("Peek element: "+names.Peek());
Console.WriteLine("Pop: "+ names.Pop());
Console.WriteLine("After Pop, Peek element: " + names.Peek());

}
}

C# Queue<T>

C# Queue<T> class is used to Enqueue and Dequeue elements. It uses the concept of
Queue that arranges elements in FIFO (First In First Out) order. It can have duplicate
elements. It is found in System.Collections.Generic namespace.

using System;
using System.Collections.Generic;

public class QueueExample


{
public static void Main(string[] args)
{
Queue<string> names = new Queue<string>();
names.Enqueue("Sonoo");
names.Enqueue("Peter");
names.Enqueue("James");
names.Enqueue("Ratan");
names.Enqueue("Irfan");

foreach (string name in names)


{
Console.WriteLine(name);
}
Console.WriteLine("Peek element: "+names.Peek());
Console.WriteLine("Dequeue: "+ names.Dequeue());
Console.WriteLine("After Dequeue, Peek element: " + names.Peek());
}
}

C# LinkedList<T>

C# LinkedList<T> class uses the concept of linked list. It allows us to insert and delete
elements fastly. It can have duplicate elements. It is found in
System.Collections.Generic namespace.
It allows us to add and remove element at before or last index.

using System;
using System.Collections.Generic;

public class LinkedListExample


{
public static void Main(string[] args)
{
// Create a list of strings
LinkedList<string> names = new LinkedList<string>();
names.AddLast("Sonoo Jaiswal");
names.AddLast("Ankit");
names.AddLast("Peter");
names.AddLast("Irfan");
names.AddFirst("John");//added to first index

// Iterate list element using foreach loop


foreach (var name in names)
{
Console.WriteLine(name);
}
}
}
❖ Writing custom generic classes.

Example 1:

class MyClass<T>
{
public T myVar;
public void SetVar(T var)
{
myVar = var;
}
public void getVar()
{
Console.WriteLine("Variable Type = {0} and Value = {1}
",typeof(T).ToString(),myVar);
}
}
class Example
{
static void Main(string[] args)
{
MyClass<int> ob = new MyClass<int>();
ob.SetVar(10);
ob.getVar();

MyClass<string> ob1 = new MyClass<string>();


ob1.SetVar("Soni College");
ob1.getVar();
Console.ReadKey();
}
}

Example 2:

class MyGenericClass<T>
{
private T genericMemberVariable;

public MyGenericClass(T value)


{
genericMemberVariable = value;
}

public T genericMethod(T genericParameter)


{
Console.WriteLine("Parameter type: {0}, value: {1}",
typeof(T).ToString(),genericParameter);
Console.WriteLine("Return type: {0}, value: {1}", typeof(T).ToString(),
genericMemberVariable);

return genericMemberVariable;
}

public T genericProperty { get; set; }


}

MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10);

int val = intGenericClass.genericMethod(200);


Console.ReadKey();

Pictorial Representation of the above code

Example 2:

Usage:

GenericTupleOfTwo<string, int> generic1=new GenericTupleOfTwo<string, int>();


GenericTupleOfTwo<string, DateTime> generic2
= new GenericTupleOfTwo<string,DateTime>();
GenericTupleOfTwo<double, DateTime> generic3
= new GenericTupleOfTwo<double,DateTime>();

Code Snippet:

/// <summary>
/// Helps to create generic class
/// </summary>
public class GenericTupleOfTwo<T1, T2>
{
private T1 first;
private T2 second;

public T1 First
{
get { return first; }
set { first = value; }
}

public T2 Second
{
get { return second; }
set { second = value; }
}

public GenericTupleOfTwo()
{

}
public GenericTupleOfTwo(T1 first, T2 second)
{
this.First = first;
this.Second = second;
}
}
❖ Working with Generic Collection Classes.

HashSet<T>

HashSet<T> supports a collection that implements a set. It uses a hash table for
storage. HashSet<T> implements a set in which all elements are unique. In other
words, duplicates are not allowed. The order of the elements is not specified. This makes
HashSet the perfect choice for working with sets of objects when order does not matter.
HashSet is a dynamic collection that grows as needed to accommodate the elements it
must store.
Here are four commonly used constructors defined by HashSet:
public HashSet( )
public HashSet(IEnumerable collection)

// Demonstrate the HashSet class.


using System;
using System.Collections.Generic;
class HashSetDemo {
static void Show(string msg, HashSet set) {
Console.Write(msg);
foreach(char ch in set)
Console.Write(ch + " ");
Console.WriteLine();
}
static void Main() {
HashSet setA = new HashSet();
HashSet setB = new HashSet();
setA.Add('A');
setA.Add('B');
setA.Add('C');
setB.Add('C');
setB.Add('D');
setB.Add('E');
Show("Initial content of setA: ", setA);
Show("Initial content of setB: ", setB);
setA.SymmetricExceptWith(setB);
Show("setA after Symmetric difference with SetB: ", setA);
setA.UnionWith(setB);
Show("setA after union with setB: ", setA);
setA.ExceptWith(setB);
Show("setA after subtracting setB: ", setA);
Console.WriteLine();
}
}

The Stack<T> Class

Stack<T> is the generic equivalent of the non-generic Stack class. Stack<T> supports a
first-in, last-out stack. Stack is a dynamic collection that grows as needed to
accommodate the elements it must store. It defines the following constructors:
public Stack( )
public Stack(int capacity)
public Stack(IEnumerable collection)

// Demonstrate the Stack class.


using System;
using System.Collections.Generic;

class GenStackDemo {
static void Main() {
Stack st = new Stack();
st.Push("One");
st.Push("Two");
st.Push("Three");
st.Push("Four");
st.Push("Five");
while(st.Count > 0) {
string str = st.Pop();
Console.Write(str + " ");
}
Console.WriteLine();
}
}

The Queue<T> Class

Queue is the generic equivalent of the non-generic Queue class. It supports a first-in,
first-out list Queue<T> is a dynamic collection that grows as needed to accommodate
the elements it must store.
It defines the following constructors:
public Queue( )
public Queue(int capacity)
public Queue(IEnumerable collection)

// Demonstrate the Queue class.


using System;
using System.Collections.Generic;

class GenQueueDemo {
static void Main() {
Queue q = new Queue();
q.Enqueue(98.6);
q.Enqueue(212.0);
q.Enqueue(32.0);
q.Enqueue(3.1416);
double sum = 0.0;
Console.Write("Queue contents: ");
while(q.Count > 0) {
double val = q.Dequeue();
Console.Write(val + " ");
sum += val;
}
Console.WriteLine("\nTotal is " + sum);
}
}

The SortedList<TKey, TValue> Class

The SortedList<TKey,TValue> class stores a sorted list of key/value pairs. It is the


generic equivalent of the non-generic SortedList<TKey,TValue> class. The size of a
SortedList<TKey,TValue> is dynamic and will automatically grow as needed. SortedList
is similar to SortedDictionary but has different performance characteristics. For example,
a SortedList<TKey,TValue> uses less memory, but a SortedDictionary is faster when
inserting out-of-order elements.
SortedList<TKey,TValue> provides many constructors.
Here is a sampling:

public SortedList( )
public SortedList(IDictionary dictionary)
public SortedList(int capacity)

// Demonstrate a SortedList.
using System;
using System.Collections.Generic;
class GenSLDemo {
static void Main() {
// Create a SortedList for
// employee names and salary.
SortedList<string,double> sl = new SortedList<string,double>();
// Add elements to the collection.
sl.Add("Butler, John", 73000);
sl.Add("Swartz, Sarah", 59000);
sl.Add("Pyke, Thomas", 45000);
sl.Add("Frank, Ed", 99000);
// Get a collection of the keys.
ICollection c = sl.Keys;
// Use the keys to obtain the values.
foreach(string str in c)
Console.WriteLine("{0}, Salary: {1:C}", str, sl[str]);
Console.WriteLine();
}
}

You might also like