0% found this document useful (0 votes)
43 views58 pages

C# Advanced Features Guide

1) The document discusses C# advanced features such as delegates, lambda expressions, events, generics, collections, and exceptions. 2) Delegates allow methods to be passed as parameters. Lambda expressions can be used when a parameter is a delegate type. 3) Common uses of delegates include starting threads, sorting collections, and handling events. Delegates are declared similar to method definitions and provide type safety.

Uploaded by

Shri Nidhi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views58 pages

C# Advanced Features Guide

1) The document discusses C# advanced features such as delegates, lambda expressions, events, generics, collections, and exceptions. 2) Delegates allow methods to be passed as parameters. Lambda expressions can be used when a parameter is a delegate type. 3) Common uses of delegates include starting threads, sorting collections, and handling events. Delegates are declared similar to method definitions and provide type safety.

Uploaded by

Shri Nidhi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 58

lOMoARcPSD|33263542

UNIT2 Notes C# - 3fwefwe

C# and .net prgramming (Sri Jayachamarajendra Polytechnic College)

Studocu is not sponsored or endorsed by any college or university


Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)
lOMoARcPSD|33263542

UNIT-II C# ADVANCED FEATURES

Delegates - Lambdas - Lambda Expressions - Events - Event Publisher - Event Listener -


Strings and Regular Expressions - Generics - Collections - Memory Management and
Pointers - Errors and Exceptions – Reflection

DELEGATES
Delegates are type-safe classes that defi ne the return types and types of parameters. The
delegate class not only contains a reference to a method, but can hold references to multiple
methods.

Lambda expressions are directly related to delegates. When the parameter is a delegate type,
you can use a lambda expression to implement a method that’s referenced from the delegate.

Delegates exist for situations in which you want to pass methods around to other methods. To
see what that means, consider this line of code: int i = int.Parse("99"); You are so used to
passing data to methods as parameters, as in this example, that you don’t consciously think
about it, so the idea of passing methods around instead of data might sound a little strange.
However, sometimes you have a method that does something, and rather than operate on data,
the method might need to do something that involves invoking another method. To
complicate things further, you do not know at compile time what this second method is. That
information is available only at runtime and hence will need to be passed in as a parameter to
the first method. That might sound confusing, but it should become clearer with a couple of
examples:

➤ Starting threads and tasks — It is possible in C# to tell the computer to start a new
sequence of execution in parallel with what it is currently doing. Such a sequence is known as
a thread, and starting one is done using the Start method on an instance of one of the base
classes, System .Threading.Thread. If you tell the computer to start a new sequence of
execution, you have to tell it where to start that sequence; that is, you have to supply the
details of a method in which execution can start. In other words, the constructor of the Thread
class takes a parameter that defi nes the method to be invoked by the thread.
➤ Generic library classes — Many libraries contain code to perform various standard tasks. It
is usually possible for these libraries to be self-contained, in the sense that you know when
you write to the library exactly how the task must be performed. However, sometimes the
task contains a subtask, which only the individual client code that uses the library knows how
to perform. For example, say that you want to write a class that takes an array of objects and

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

sorts them in ascending order. Part of the sorting process involves repeatedly taking two of
the objects in the array and comparing them to see which one should come fi rst. If you want
to make the class capable of sorting arrays of any object, there is no way that it can tell in
advance how to do this comparison. The client code that hands your class the array of objects
must also tell your class how to do this comparison for the particular objects it wants sorted.
The client code has to pass your class details of an appropriate method that can be called to
do the comparison.
➤ Events — The general idea here is that often you have code that needs to be informed
when some event takes place. GUI programming is full of situations similar to this. When the
event is raised, the runtime needs to know what method should be executed. This is done by
passing the method that handles the event as a parameter to a delegate.

Declaring Delegates
When you want to use a class in C#, you do so in two stages. First, you need to defi ne the
class — that is, you need to tell the compiler what fi elds and methods make up the class.
Then (unless you are using only static methods), you instantiate an object of that class. With
delegates it is the same process. You start by declaring the delegates you want to use.
Declaring delegates means telling the compiler what kind of method a delegate of that type
will represent. Then, you have to create one or more instances of that delegate. Behind the
scenes, the compiler creates a class that represents the delegate. The syntax for declaring
delegates looks like this:

delegate void IntMethodInvoker(int x);

This declares a delegate called IntMethodInvoker, and indicates that each instance of this
delegate can hold a reference to a method that takes one int parameter and returns void. The
crucial point to understand about delegates is that they are type-safe. When you defi ne the
delegate, you have to provide full details about the signature and the return type of the
method that it represents.

NOTE One good way to understand delegates is to think of a delegate as something that
gives a name to a method signature and the return type. Suppose that you want to defi ne a
delegate called TwoLongsOp that will represent a method that takes two longs as its
parameters and returns a double.

You could do so like this:


delegate double TwoLongsOp(long first, long second);

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Or, to defi ne a delegate that will represent a method that takes no parameters and returns a
string, you might write this:
delegate string GetAString();

The syntax is similar to that for a method definition, except there is no method body and the
definition is prefixed with the keyword delegate. Because what you are doing here is
basically defining a new class, you can defi ne a delegate in any of the same places that you
would defi ne a class — that is to say, either inside another class, outside of any class, or in a
namespace as a top-level object. Depending on how visible you want your definition to be,
and the scope of the delegate, you can apply any of the normal access modifiers to delegate
definitions — public, private, protected, and so on

Using Delegates

The following code snippet demonstrates the use of a delegate. It is a rather long-winded way
of calling the ToString method on an int (code fi le GetAStringDemo/Program.cs):

Simple Delegate Example


This example defines a MathOperations class that uses a couple of static methods to perform
two operations on doubles. Then you use delegates to invoke these methods. The math class
looks like this:

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Running this example gives you the following:

Instead of defi ning a new delegate type with every parameter and return type, you can use
the Action and Func delegates. The generic Action delegate is meant to reference a method
with void return. This delegate class exists in different variants so that you can pass up to 16
different parameter types. The Action class without the generic parameter is for calling
methods without parameters. Action is for calling a method with one parameter; Action for a
method with two parameters; and Action for a method with eight parameters.

The Func delegates can be used in a similar manner. Func allows you to invoke methods with
a return type. Similar to Action, Func is defi ned in different variants to pass up to 16
parameter types and a return type. Func is the delegate type to invoke a method with a return
type and without parameters. Func is for a method with one parameter, and Func is for a
method with four parameters.

The example in the preceding section declared a delegate with a double parameter and a
double return type:

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

lamda:

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

lambda expressions. Lambda expressions can be used whenever you have a delegate
parameter type. The previous example using anonymous methods is modifi ed here to use a
lambda expression.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

With the publisher class CarDealer there’s no need to change anything. It has the same
implementation as before.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

GENRICS

There are some significant characteristics of Generic types that make them special to the
conventional non-generics type as follows;

 Type Safety

 Performance

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

 Binary Code reuse

Type Safety

One of the most significant features of Generics is Type Safety. In the case of the non-generic
ArrayList class, if objects are used, any type can be added to the collections that can
sometimes result in a great disaster. The following example shows adding an integer, string
and object to the collection of an ArrayList type;

ArrayList obj = new ArrayList();


obj.Add(50);
obj.Add("Dog");
obj.Add(new TestClass());
C#
Copy

Now, if the collection is iterated through the foreach statement using integer elements, the
compiler accepts the code but because all the elements in the collection are not an integer, a
runtime exception occurs;

foreach(int i in obj)
{
Console.WriteLine(i);
}

The rule of thumb in programming is that Errors should be detected as early as possible. With
the generic class Test<T>, the generic type T defines what types are allowed. With the
definition of Test<int>, only an integer type can be added to the collection. The compiler
doesn't compile the code because the Add() method has invalid arguments as follows;

Test<int> obj = new Test<int>();


obj.Add(50);
obj.Add("Dog"); //compiler error
obj.Add(new TestClass()); //compiler error
C#
Copy
Performance

Another feature of Generics is performance. Using value types with non-generic collection
classes result in boxing and unboxing overhead when a value type is converted to reference
type and vice-versa.

In the following example, the ArrayList class stores objects and the Add() method is defined
to store some integer type argument. So an integer type is boxed. When the value from
ArrayList is read using the foreach statement, unboxing occurrs.

ArrayList obj = new ArrayList();


obj.Add(50); //boxing- convert value type to reference type
int x= (int)obj[0]; //unboxing
foreach(int i in obj)
{
Console.WriteLine(i); // unboxing

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

}
Note

Generics are faster than other collections such as ArrayList.

Instead of using objects, a Generics type of the TestClass<T> class is defined as an int, so an
int type is used inside the class that is generated dynamically from the compiler. Therefore
boxing and unboxing no longer occurs as in the following;

TestClass<int> obj = new TestClass<int>();


obj.Add(50); //No boxing
int x= obj[0]; // No unboxing
foreach(int i in obj)
{
Console.WriteLine(i); //No unboxing
}
Binary Code reuse

Generics provide a kind of source code protection. A Generic class can be defined once and
can be instantiated with many different types. Generics can be defined in one CLR supported
language and used from another .NET language. The following TestClass<T> is instantiated
with an int and string types:

TestClass<int> obj = new TestClass<int>();


obj.Add(50);

TestClass<string> obj1 = new TestClass<string>();


Obj1.Add("hello");

Generics allow you to define the specification of the data type of programming elements in a
class or a method, until it is actually used in the program. In other words, generics allow you
to write a class or method that can work with any data type.

C# allows you to define generic classes, interfaces, abstract classes, fields, methods, static
methods, properties, events, delegates, and operators using the type parameter and without
the specific data type. A type parameter is a placeholder for a particular type specified
when creating an instance of the generic type.

A generic type is declared by specifying a type parameter in an angle brackets after a type
name, e.g. TypeName<T> where T is a type parameter.

The Generic class can be defined by putting the <T> sign after the class name. It isn't
mandatory to put the "T" word in the Generic type definition. You can use any word in the
TestClass<> class declaration.

public class TestClass<T> { }

The System.Collection.Generic namespace also defines a number of classes that implement


many of these key interfaces. The following table describes the core class types of this
namespace.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Generic class Description


The basis for a generic collection Comparer compares two generic objects
Collection<T>
for equality
Dictionary<TKey,
A generic collection of name/value pairs
TValue>
List<T> A dynamically resizable list of Items
Queue<T> A generic implementation of a first-in, first-out (FIFO) list
Stack<T> A generic implementation of a last-in, first-out (LIFO) list

Generic Class

Generic classes are defined using a type parameter in an angle brackets after the class
name. The following defines a generic class.

Example: Define Generic Class


class DataStore<T>
{
public T Data { get; set; }
}

Above, the DataStore is a generic class. T is called type parameter, which can be used as a
type of fields, properties, method parameters, return types, and delegates in
the DataStore class. For example, Data is generic property because we have used a type
parameter T as its type instead of the specific data type.

Instantiating Generic Class

You can create an instance of generic classes by specifying an actual type in angle
brackets. The following creates an instance of the generic class DataStore.

DataStore<string> store = new DataStore<string>();

Above, we specified the string type in the angle brackets while creating an instance.
So, T will be replaced with a string type wherever T is used in the entire class at compile-
time. Therefore, the type of Data property would be a string.

Example: Generic class


DataStore<string> strStore = new DataStore<string>();
strStore.Data = "Hello World!";
//strStore.Data = 123; // compile-time error

DataStore<int> intStore = new DataStore<int>();


intStore.Data = 100;
//intStore.Data = "Hello World!"; // compile-time error

KeyValuePair<int, string> kvp1 = new KeyValuePair<int, string>();


kvp1.Key = 100;
kvp1.Value = "Hundred";

KeyValuePair<string, string> kvp2 = new KeyValuePair<string, string>();

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

kvp2.Key = "IT";
kvp2.Value = "Information Technology";
Generic Class Characteristics

 A generic class increases the reusability. The more type parameters mean more
reusable it becomes. However, too much generalization makes code difficult to
understand and maintain.
 A generic class can be a base class to other generic or non-generic classes or abstract
classes.
 A generic class can be derived from other generic or non-generic interfaces, classes,
or abstract classes.

Simple Generic Class Example


using System;
using System.Collections.Generic;

namespace GenericApp
{
public class TestClass<T>
{
// define an Array of Generic type with length 5
T[] obj = new T[5];
int count = 0;

// adding items mechanism into generic type


public void Add(T item)
{
//checking length
if (count + 1 < 6)
{
obj[count] = item;

}
count++;
}
//indexer for foreach statement iteration
public T this[int index]

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

{
get { return obj[index]; }
set { obj[index] = value; }
}
}
class Program
{
static void Main(string[] args)
{
//instantiate generic with Integer
TestClass<int> intObj = new TestClass<int>();

//adding integer values into collection


intObj.Add(1);
intObj.Add(2);
intObj.Add(3); //No boxing
intObj.Add(4);
intObj.Add(5);

//displaying values
for (int i = 0; i < 5; i++)
{
Console.WriteLine(intObj[i]); //No unboxing
}
Console.ReadKey();
}
}

Generic Fields

A generic class can include generic fields. However, it cannot be initialized.

Example: Generic Field

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

class DataStore<T>
{
public T data;
}

The following declares a generic array.

Example: Generic Array


class DataStore<T>
{
public T[] data = new T[10];
}

Generic Methods

A method declared with the type parameters for its return type or parameters is called a
generic method.

Example: Generic Methods


class DataStore<T>
{
private T[] _data = new T[10];

public void AddOrUpdate(int index, T item)


{
if(index >= 0 && index < 10)
_data[index] = item;
}

public T GetData(int index)


{
if(index >= 0 && index < 10)
return _data[index];
else
return default(T);
}
}

Above, the AddorUpdate() and the GetData() methods are generic methods. The actual
data type of the item parameter will be specified at the time of instantiating
the DataStore<T> class, as shown below.

Example: Generic Methods


DataStore<string> cities = new DataStore<string>();
cities.AddOrUpdate(0, "Mumbai");
cities.AddOrUpdate(1, "Chicago");
cities.AddOrUpdate(2, "London");

DataStore<int> empIds = new DataStore<int>();


empIds.AddOrUpdate(0, 50);
empIds.AddOrUpdate(1, 65);

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

empIds.AddOrUpdate(2, 89);

The generic parameter type can be used with multiple parameters with or without non-
generic parameters and return type. The followings are valid generic method overloading.

Example: Generic Method Overloading


public void AddOrUpdate(int index, T data) { }
public void AddOrUpdate(T data1, T data2) { }
public void AddOrUpdate<U>(T data1, U data2) { }
public void AddOrUpdate(T data) { }

A non-generic class can include generic methods by specifying a type parameter in angle
brackets with the method name, as shown below.

Example: Generic Method in Non-generic Class


class Printer
{
public void Print<T>(T data)
{
Console.WriteLine(data);
}
}

Printer printer = new Printer();


printer.Print<int>(100);
printer.Print(200); // type infer from the specified value
printer.Print<string>("Hello");
printer.Print("World!"); // type infer from the specified value

using System;
using System.Collections.Generic;

namespace GenericApp
{
class Program
{
//Generic method
static void Swap<T>(ref T a, ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
// Swap of two integers.
int a = 40, b = 60;
Console.WriteLine("Before swap: {0}, {1}", a, b);

Swap<int>(ref a, ref b);

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Console.WriteLine("After swap: {0}, {1}", a, b);

Console.ReadLine();
}
}

Advantages of Generics

1. Generics increase the reusability of the code. You don't need to write code to handle
different data types.
2. Generics are type-safe. You get compile-time errors if you try to use a different data
type than the one specified in the definition.
3. Generic has a performance advantage because it removes the possibilities of boxing
and unboxing.

Memory Management and Pointers:-

Value Data Types Windows uses a system known as virtual addressing, in which the mapping
from the memory address seen by your program to the actual location in hardware memory is
entirely managed by Windows. As a result, each process on a 32-bit processor sees 4GB of
available memory, regardless of how much hardware memory you actually have in your
computer (on 64-bit processors this number is greater). This memory contains everything that
is part of the program, including the executable code, any DLLs loaded by the code, and the
contents of all variables used when the program runs. This 4GB of memory is known as the
virtual address space or virtual memory. For convenience, this chapter uses the shorthand
memory. Each memory location in the available 4GB is numbered starting from zero. To
access a value stored at a particular location in memory, you need to supply the number that
represents that memory location. In any compiled high-level language, including C#, Visual
Basic, C++, and Java, the compiler converts human-readable variable names into memory
addresses that the processor understands.
Somewhere inside a processor’s virtual memory is an area known as the stack. The stack
stores value data types that are not members of objects. In addition, when you call a method,
the stack is used to hold a copy of any parameters passed to the method. To understand how
the stack works, you need to understand the importance of variable scope in C#. If variable a
goes into scope before variable b, then b will always go out of scope fi rst. Consider the
following code: { int a; // do something { int b; // do something else } } First, a is declared.
Then, inside the inner code block, b is declared. Then the inner code block terminates and b
goes out of scope, then a goes out of scope. Therefore, the lifetime of b is entirely contained
within the lifetime of a. The idea that you always deallocate variables in the reverse order of
how you allocate them is crucial to the way the stack works. Note that b is in a different block
from code (defi ned by a different nesting of curly braces). For this reason, it is contained
within a different scope. This is termed as block scope or structure scope.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Reference Data Types Although the stack provides very high performance, it is not fl exible
enough to be used for all variables. The requirement that the lifetime of a variable must be
nested is too restrictive for many purposes. Often, you need to use a method to allocate
memory for storing data and keeping that data available long after that method has exited.
This possibility exists whenever storage space is requested with the new operator — as is the
case for all reference types. That is where the managed heap comes in.

Garbage Collection:
When the garbage collector runs, it removes all those objects from the heap that are no longer
referenced. Immediately after doing this, the heap will have objects scattered on it, mixed up
with memory that has just been freed (see Figure 14-4). If the managed heap stayed like this,
allocating space for new objects would be an awkward process, with the runtime having to
search through the heap for a block of memory big enough to store each new object.
However, the garbage collector does not leave the heap in this state. As soon as the garbage
collector has freed up all the objects it can, it compacts the heap by moving all the remaining
objects to form one continuous block of memory. This means that the heap can continue
working just like the stack, as far as locating where to store new objects. Of course, when the
objects are moved about, all the references to those objects need to be updated with the
correct new addresses, but the garbage collector handles that too.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

FREEING UNMANAGED RESOURCES


The presence of the garbage collector means that you usually do not need to worry about
objects you no longer need; you simply allow all references to those objects to go out of
scope and let the garbage collector free memory as required. However, the garbage collector
does not know how to free unmanaged resources (such as fi le handles, network connections,
and database connections). When managed classes encapsulate direct or indirect references to
unmanaged resources, you need to make special provisions to ensure that the unmanaged
resources are released when an instance of the class is garbage collected. When defi ning a
class, you can use two mechanisms to automate the freeing of unmanaged resources. These
mechanisms are often implemented together because each provides a slightly different
approach: ➤ Declare a destructor (or fi nalizer) as a member of your class. ➤ Implement the
System.IDisposable interface in your class. The following sections discuss each of these
mechanisms in turn, and
Destructors
You have seen that constructors enable you to specify actions that must take place whenever
an instance of a class is created. Conversely, destructors are called before an object is
destroyed by the garbage collector. Given this behavior, a destructor would initially seem like
a great place to put code to free unmanaged resources and perform a general clean up.
Unfortunately, things are not so straightforward

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

The IDisposable Interface


In C#, the recommended alternative to using a destructor is using the System.IDisposable
interface. The IDisposable interface defi nes a pattern (with language-level support) that
provides a deterministic mechanism for freeing unmanaged resources and avoids the garbage
collector–related problems inherent with destructors. The IDisposable interface declares a
single method named Dispose, which takes no parameters and returns void. Here is an
implementation for MyClass

Pointers:-
A pointer is simply a variable that stores the address of something else in the same way as a
reference.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

REFLECTION
Reflection is a generic term that describes the capability to inspect and manipulate program
elements at runtime. For example, reflection allows you to do the following:

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

➤ Enumerate the members of a type


➤ Instantiate a new object
➤ Execute the members of an object
➤ Find out information about a type
➤ Find out information about an assembly
➤ Inspect the custom attributes applied to a type
➤ Create and compile a new assembly
CUSTOM ATTRIBUTES:-
The .NET Framework also enables you to defi ne your own attributes. Obviously, these
attributes won’t have any effect on the compilation process because the compiler has no
intrinsic awareness of them. However, these attributes will be emitted as metadata in the
compiled assembly when they are applied to program elements. By itself, this metadata might
be useful for documentation purposes, but what makes attributes really powerful is that by
using refl ection, your code can read this metadata and use it to make decisions at runtime.
This means that the custom attributes that you defi ne can directly affect how your code runs.
For example, custom attributes can be used to enable declarative code access security checks
for custom permission classes, to associate information with program elements that can then
be used by testing tools, or when developing extensible frameworks that allow the loading of
plug-ins or modules

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

AttributeUsage Attribute:-

The members of the AttributeTargets enumeration are as follows: ➤ All ➤ Assembly ➤ Class
➤ Constructor ➤ Delegate ➤ Enum ➤ Event ➤ Field ➤ GenericParameter (.NET 2.0 and
higher only) ➤ Interface ➤ Method ➤ Module ➤ Parameter ➤ Property ➤ ReturnValue ➤
Struct

C# Exception Handling

Exception Handling in C# is a process to handle runtime errors. We perform exception


handling so that normal flow of the application can be maintained even after runtime errors.

In C#, exception is an event or object which is thrown at runtime. All exceptions the derived
from System.Exception class. It is a runtime error which can be handled. If we don't handle
the exception, it prints exception message and terminates the program.

Advantage

It maintains the normal flow of the application. In such case, rest of the code is executed
event after exception.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

C# Exception Classes

All the exception classes in C# are derived from System.Exception class. Let's see the list of
C# common exception classes.

Exception Description

System.DivideByZeroException handles the error generated by dividing a number with


zero.

System.NullReferenceExceptio handles the error generated by referencing the null


n object.

System.InvalidCastException handles the error generated by invalid typecasting.

System.IO.IOException handles the Input Output errors.

System.FieldAccessException handles the error generated by invalid private or


protected field access.

Two important classes in the hierarchy are derived from System.Exception:


➤ SystemException — This class is for exceptions that are usually thrown by the .NET
runtime or that are considered to be of a generic nature and might be thrown by almost any
application. For example, StackOverflowException is thrown by the .NET runtime if it
detects that the stack is full. However, you might choose to throw ArgumentException or its
subclasses in your own code if you detect that a method has been called with inappropriate
arguments. Subclasses of SystemException include classes that represent both fatal and
nonfatal errors.
➤ ApplicationException — With the initial design of the .NET Framework, this class was
meant to be the base class for custom application exception classes. However, some
exception classes that are thrown by the CLR derive from this base class (e.g.,
TargetInvocationException), and exceptions thrown from applications derive from
SystemException (e.g., ArgumentException). Therefore, it’s no longer a good practice to
derive custom exception types from ApplicationException, as this doesn’t offer any benefi ts.
Instead, custom exception classes can derive directly from the Exception base class. Many
exception classes in the .NET Framework directly derive from Exception.

An exception is a problem that arises during the execution of a program. A C# exception is a


response to an exceptional circumstance that arises while a program is running, such as an
attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C#
exception handling is built upon four keywords: try, catch, finally, and throw.
 try − A try block identifies a block of code for which particular exceptions is
activated. It is followed by one or more catch blocks.

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

 catch − A program catches an exception with an exception handler at the place in a


program where you want to handle the problem. The catch keyword indicates the
catching of an exception.
 finally − The finally block is used to execute a given set of statements, whether an
exception is thrown or not thrown. For example, if you open a file, it must be closed
whether an exception is raised or not.
 throw − A program throws an exception when a problem shows up. This is done
using a throw keyword.

Syntax

Assuming a block raises an exception, a method catches an exception using a combination of


the try and catch keywords. A try/catch block is placed around the code that might generate
an exception. Code within a try/catch block is referred to as protected code, and the syntax
for using try/catch looks like the following −
try {
// statements causing exception
} catch( ExceptionName e1 ) {
// error handling code
} catch( ExceptionName e2 ) {
// error handling code
} catch( ExceptionName eN ) {
// error handling code
} finally {
// statements to be executed
}

C# try/catch

In C# programming, exception handling is performed by try/catch statement. The try


block in C# is used to place the code that may throw exception. The catch block is used to
handled the exception. The catch block must be preceded by try block.

C# example without try/catch


1. using System;
2. public class ExExample
3. {
4. public static void Main(string[] args)
5. {
6. int a = 10;
7. int b = 0;
8. int x = a/b;
9. Console.WriteLine("Rest of the code");
10. }
11. }

Output:

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.

C# try/catch example
1. using System;
2. public class ExExample
3. {
4. public static void Main(string[] args)
5. {
6. try
7. {
8. int a = 10;
9. int b = 0;
10. int x = a / b;
11. }
12. catch (Exception e) { Console.WriteLine(e); }
13.
14. Console.WriteLine("Rest of the code");
15. }
16. }

Output:

System.DivideByZeroException: Attempted to divide by zero.


Rest of the code

C# finally

C# finally block is used to execute important code which is to be executed whether exception
is handled or not. It must be preceded by catch or try block.

C# finally example if exception is handled

1. using System;
2. public class ExExample
3. {
4. public static void Main(string[] args)
5. {
6. try
7. {
8. int a = 10;
9. int b = 0;

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

10. int x = a / b;
11. }
12. catch (Exception e) { Console.WriteLine(e); }
13. finally { Console.WriteLine("Finally block is executed"); }
14. Console.WriteLine("Rest of the code");
15. }
16. }

Output:

System.DivideByZeroException: Attempted to divide by zero.


Finally block is executed
Rest of the code

Multiple Catch Blocks

A try block can throw multiple exceptions, which can handle by using multiple catch blocks.
Remember that more specialized catch block should come before a generalized one.
Otherwise the compiler will show a compilation error.

1. //C#: Exception Handling: Multiple catch


2. using System;
3. class MyClient
4. {
5. public static void Main()
6. {
7. int x = 0;
8. int div = 0;
9. try
10. {
11. div = 100 / x;
12. Console.WriteLine("Not executed line");
13. }
14. catch (DivideByZeroException de)
15. {
16. Console.WriteLine("DivideByZeroException");
17. }
18. catch (Exception)
19. {
20. Console.WriteLine("Exception");
21. }
22. finally
23. {
24. Console.WriteLine("Finally Block");
25. }
26. Console.WriteLine($"Result is {div}");
27. }

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

28. }

Catching all Exceptions

By providing a catch block without brackets or arguments, we can catch all exceptions
occurred inside a try block. Even we can use a catch block with an Exception type parameter
to catch all exceptions happened inside the try block since in C#, all exceptions are directly or
indirectly inherited from the Exception class.

1. //C#: Exception Handling: Handling all exceptions


2. using System;
3. class MyClient
4. {
5. public static void Main()
6. {
7. int x = 0;
8. int div = 0;
9. try
10. {
11. div = 100 / x;
12. Console.WriteLine("Not executed line");
13. }
14. catch
15. {
16. Console.WriteLine("oException");
17. }
18. Console.WriteLine($"Result is {div}");
19. }
20. }

Throwing an Exception

In C#, it is possible to throw an exception programmatically. The 'throw' keyword is used for
this purpose. The general form of throwing an exception is as follows.

1. throw exception_obj;

For example, the following statement throws an ArgumentException explicitly.

1. throw new ArgumentException("Exception");


2.
3. //C#: Exception Handling:
4. using System;
5. class MyClient
6. {
7. public static void Main()
8. {
9. try
10. {
11. throw new DivideByZeroException("Invalid Division");
12. }

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

13. catch (DivideByZeroException)


14. {
15. Console.WriteLine("Exception");
16. }
17. Console.WriteLine("LAST STATEMENT");
18. }
19. }

Re-throwing an Exception

The exceptions, which we caught inside a catch block, can re-throw to a higher context by
using the keyword throw inside the catch block. The following program shows how to do
this.

1. //C#: Exception Handling: Handling all exceptions


2. using System;
3. class MyClass
4. {
5. public void Method()
6. {
7. try
8. {
9. int x = 0;
10. int sum = 100 / x;
11. }
12. catch (DivideByZeroException)
13. {
14. throw;
15. }
16. }
17. }
18. class MyClient
19. {
20. public static void Main()
21. {
22. MyClass mc = new MyClass();
23. try
24. {
25. mc.Method();
26. }
27. catch (Exception)
28. {
29. Console.WriteLine("Exception caught here");
30. }
31. Console.WriteLine("LAST STATEMENT");
32. }
33. }

User-defined Exceptions

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)


lOMoARcPSD|33263542

In C#, it is possible to create our own exception class. But Exception must be the ultimate
base class for all exceptions in C#. So the user-defined exception classes must inherit from
either Exception class or one of its standard derived classes.

1. //C#: Exception Handling: User defined exceptions


2. using System;
3. class MyException : Exception
4. {
5. public MyException(string str)
6. {
7. Console.WriteLine("User defined exception");
8. }
9. }
10. class MyClient
11. {
12. public static void Main()
13. {
14. try
15. {
16. throw new MyException("RAJESH");
17. }
18. catch (Exception)
19. {
20. Console.WriteLine("Exception caught here" + e.ToString());
21. }
22. Console.WriteLine("LAST STATEMENT");
23. }
24. }

Downloaded by 4057 PRAISY SANTHA M P (malarponasir02@gmail.com)

You might also like