C#
C#
C#
Part 1 - Introduction................................................................................................................................. 4
Part 2 - Reading and writing to a console ........................................................................................ 4
Part 3 - Built - in types .............................................................................................................................. 4
Part 4 - String type.................................................................................................................................... 4
Part 5 - Common Operators ................................................................................................................. 4
Part 6 - Nullable Types ............................................................................................................................ 5
Part 7 - Datatypes conversion .............................................................................................................. 5
Part 8 - Arrays ............................................................................................................................................ 5
Part 9 - Comments ................................................................................................................................... 5
Part 10 - If statement ............................................................................................................................... 5
Part 11 - switch statement ..................................................................................................................... 5
Part 16 - Methods ..................................................................................................................................... 5
Part 17 - Method parameters ............................................................................................................... 5
Part 18 - Namespaces ............................................................................................................................ 7
Part 19 Introduction to Classes.......................................................................................................... 8
Part 20 - Static and instance class members ................................................................................. 10
Part 21 - Inheritance .............................................................................................................................. 12
Part 22 - Method hiding ....................................................................................................................... 14
Part 23 - Polymorphism ......................................................................................................................... 15
Part 24 - Difference between method overriding and method hiding ................................. 21
Part 25 - Method overloading ............................................................................................................ 21
Part 26 - Why Properties ....................................................................................................................... 22
Part 27 Properties ................................................................................................................................ 23
Part 28 Structs....................................................................................................................................... 24
Part 29 - Difference between classes and structs ........................................................................ 25
Part 30 - Interfaces................................................................................................................................. 27
Part 31 - Explicit interfaces implementation ................................................................................... 29
Part 32 - Abstract classes ..................................................................................................................... 30
Part 33 - Difference between abstract classes and interfaces ................................................ 31
Part 34 - Problems of multiple class inheritance............................................................................ 32
Part 35 - Multiple class inheritance using interfaces .................................................................... 33
Part 36 - Delegates ................................................................................................................................ 33
Part 37 - Delegates usage ................................................................................................................... 34
Part 38 - Delegates usage continued .............................................................................................. 34
Part 39 - Multicast Delegates.............................................................................................................. 35
Part 40 - Exception Handling .............................................................................................................. 36
Part 41 - Inner Exceptions .................................................................................................................... 37
Part 42 - Custom Exceptions ............................................................................................................... 38
Part 43 - Exception handling abuse ................................................................................................. 39
Part 44 - Preventing exception handling abuse ........................................................................... 40
Part 45 - Why Enums .............................................................................................................................. 41
Part 46 - Enums Example ...................................................................................................................... 41
Part 47 Enums ....................................................................................................................................... 41
Part 48 - Difference between Types and Type Members ........................................................... 43
Part 49 - Access Modifiers Private, Public & Protected ............................................................ 44
Part 50 - Access Modifiers Internal and Protected Internal .................................................... 44
Part 51 - Access Modifiers for types .................................................................................................. 45
Part 52 - Attributes ................................................................................................................................. 45
Part 53 - Reflection ................................................................................................................................ 46
Part 54 - Reflection Example............................................................................................................... 48
Part 55 - Late binding using reflection ............................................................................................. 48
Part 56 Generics .................................................................................................................................. 49
Part 57 - Why should you override ToString Method .................................................................... 50
Part 58 - Why should you override Equals Method ...................................................................... 50
Part 59 - Difference between Convert.ToString and ToString ................................................... 51
Part 60 - Difference between String and StringBuilder ................................................................ 52
Part 61 - Partial classes ......................................................................................................................... 53
Part 62 - Creating partial classes ....................................................................................................... 54
Part 63 - Partial methods ...................................................................................................................... 55
Part 64 - How and where are indexers used in .net ..................................................................... 56
Part 65 - Indexers .................................................................................................................................... 58
Part 66 - Overloading indexers........................................................................................................... 58
Part 67 - Optional parameters ........................................................................................................... 58
Part 68 - Making method parameters optional using method overloading ........................ 58
Part 69 - Making method parameters optional by specifying parameter defaults ........... 58
Part 70 - Making method parameters optional by using OptionalAttribute......................... 58
Part 71 - Code snippets in visual studio ........................................................................................... 58
Part 72 - What is dictionary.................................................................................................................. 58
Part 73 - What is dictionary continued ............................................................................................ 58
Part 74 - List collection class ................................................................................................................ 59
Part 75 - List collection class continued........................................................................................... 59
Part 76 - Working with generic list class and ranges .................................................................... 59
Part 77 - Sort a list of simple types ..................................................................................................... 59
Part 78 - Sort a list of complex types ................................................................................................. 59
Part 79 - Sort a list of complex types using Comparison delegate .......................................... 59
Part 80 - Some useful methods of List collection class ................................................................ 59
Part 81 - When to use a dictionary over list .................................................................................... 59
Part 82 - Generic queue collection class ........................................................................................ 59
Part 83 - Generic stack collection class .......................................................................................... 59
Part 84 - Real time example of queue collection class .............................................................. 59
Part 85 - Real time example of stack collection class ................................................................. 59
Part 86 - Multithreading ........................................................................................................................ 60
Part 87 - Advantages and disadvantages of multithreading ................................................... 60
Part 88 - ThreadStart delegate ........................................................................................................... 60
Part 89 - ParameterizedThreadStart delegate .............................................................................. 60
Part 90 - Passing data to the Thread function in a type safe manner.................................... 60
Part 91 - Retrieving data from Thread function using callback method ............................... 60
Part 92 - Significance of Thread Join and Thread IsAlive functions ......................................... 60
Part 93 - Protecting shared resources from concurrent access in multithreading.............. 60
Part 94 - Difference between Monitor and lock ........................................................................... 60
Part 95 - Deadlock in a multithreaded program .......................................................................... 60
Part 96 - How to resolve a deadlock in a multithreaded program ......................................... 60
Part 97 - Performance of a multithreaded program ................................................................... 60
Part 98 - Anonymous methods ........................................................................................................... 60
Part 99 - Lambda expression .............................................................................................................. 61
Part 100 - Func delegate ..................................................................................................................... 61
Part 1 - Introduction
.Net we have deployed multiple application,
- Web - Console - Sharepoint
- Office - Window - WebService
Console Application: This is nothing but commend prompt.
1. Create Console Application
2. Write Simple Program, Console can be called inside the System
using System;
class SampleProgram
{
public static void Main()
{
Console.WriteLine("Welcome");
}
}
Using Declaration: A namespace is used to organize your code and is collection of
1. Class Instance & Static class
2. Interface
3. Structs
4. Enum
5. Delegates
Main method is the entry point of the code-behind application,
Every console application should have Main() function, & its an entry point to run
application.
using System;
class SampleProgram
{
public static void Main1()
{
Console.WriteLine("Welcome Inner Function");
}
public static void Main()
{ //the list of function should called only if we declare inside Main()
Console.WriteLine("Welcome");
Main1();
}
}
Part 2 - Reading and writing to a console
In a program
Part 3 - Built - in types
In a program
Part 4 - String type
In a program
Part 5 - Common Operators
In a program
Part 6 - Nullable Types
In a program
Part 7 - Datatypes conversion
In a program
Part 8 - Arrays
In a program
Part 9 - Comments
In a program
Part 10 - If statement
In a program
Part 11 - switch statement
In a program
Part 16 - Methods
Instance/Non-Static Method Static Method
1. Instance methods are methods that 1. Static methods are methods that are
are associated with objects of a class associated with a class
2. When no static modifier presents that 2. Method declaration includes a static
method called as instance class modifier called static class
3. Instance method involved using an 3. Static method involved using the class
instance of the class name
4. If multiple instances of the class can be 4. In method of static, there are no
created/initiated and each instance instances of that method, and you can
has its own separate method. invoke only that one definition of the
5. Instance method usually possesses a static method
reference to the object that called the 5. this keyword cannot be used in static
method and it can be accessed using methods since they are not associated
the this keyword inside the method with a particular object
class Program class Program
{ {
public static void Main() public static void Main()
{ {
Program p = new Program(); Program.EvenNumber(50);
int Sum = p.Add(10, 20); }
Console.WriteLine("Total count: {0}", Sum); public static void EvenNumber(int Target)
} {
public int Add(int FN, int SN) int intStart = 0;
{ while (intStart <= Target)
return FN + SN; {
} Console.WriteLine(intStart);
} intStart = intStart + 2;
}
}
}
Output Parameter:
Use when you want a method to return more than one value.
class Program
{
public static void Main()
{
int Total = 0;
int Product = 0;
Calculator(10, 20, out Total, out Product);
Console.WriteLine("Total: {0}, Product: {1}", Total, Product);
}
public static void Calculator(int FN, int SN, out int Sum, out int Product)
{
Sum = FN + SN;
Product = FN * SN;
}
}
Output: Total: 30, Product: 200
Parameter Arrays:
The params keyword lets you specify a method parameter that takes a variable number
of arguments. You can send a comma-separated list of arguments, or an array, or no
arguments.
Params keyword should be the last one in the method declaration (e.g., public static
void ParameterMtd(int i, int j, params int[] Numbers) ),and only one params
keyword is permitted in a method declaration. (e.g., Not allowed - public static void
ParameterMtd(params string[] Name, params int[] Numbers))
class Program
{
public static void Main()
{
int[] Numbers = new int[3];
Numbers[0] = 12;
Numbers[1] = 13;
Numbers[2] = 14;
//ParameterMtd();
//ParameterMtd(Numbers);
ParameterMtd(1, 2, 3, 4, 5); //Method Argument
}
/*Parameter allows null argument only if params used*/
public static void ParameterMtd(params int[] Numbers) //Method Parameter
{
Console.WriteLine("There are {0} elements in an Array", Numbers.Length);
foreach (int i in Numbers)
{
Console.WriteLine(i);
}
}
}
Output ParameterMtd(1, 2, 3, 4, 5);
ParameterMtd(); There are 5 elements in an Array
There are 0 elements in an Array 1
ParameterMtd(Numbers); 2
There are 3 elements in an Array 3
12 4
13 5
14
Part 18 Difference b/w value and Reference Parameter
Part 18 - Namespaces
Why Namespace? Namespaces are used to organize your programs. They also provide
assistance in avoiding name clashes.
Namespace dont corresponding to file, directory or assembly names. They could be written in
separate files and / or separate assemblies and still belongs to same namespace.
Namespace can be nested in 2 ways.
Namespace alias directives. Sometimes you may encounter a long namespace and wish to
have it shorter. This could improve readability and avoid name clashes with similarly named
methods.
fully qualified name
alias directives
using PATA = ProjectA.TeamA;
using PATB = ProjectB.TeamA;
class Program
{
public static void Main()
{
PATA.ClassA.Print();
PATB.classA.Print();
}
}
namespace ProjectA
{
namespace TeamA
{
class ClassA
{
public static void Print()
{
Console.WriteLine("Testing Project A --> Team A --> Class A");
}
}
}
}
namespace ProjectB
{
namespace TeamA
{
class classA
{
public static void Print()
{
Console.WriteLine("Testing Project B -->Team A --> Class A");
}
}
}
}
Avoid ambiguity using fully qualified name
Part 21 - Inheritance
Why Inheritance: A lot of code between these 2 classes is duplicate
using System;
public class Employee
{ O/P:
public string FirstName; Full Name: Full, Time
public string LastName; Salary: 50000
public string email;
public void PrintFullName()
Full Name: Part, Time
{ Salary: 60000
Console.WriteLine("Full Name: {0}, {1}", FirstName, LastName);
}
}
public class FullTimeEmployee : Employee
{
public float MonthlySalary;
}
public class PartTimeEmployee: Employee
{
public float HourlyRate;
}
class Program
{
public static void Main()
{
FullTimeEmployee FTE = new FullTimeEmployee();
FTE.FirstName = "Full";
FTE.LastName = "Time";
FTE.MonthlySalary = 50000;
FTE.PrintFullName();
Console.WriteLine("Salary: {0}", FTE.MonthlySalary);
PartTimeEmployee PTE = new PartTimeEmployee();
PTE.FirstName = "Part";
PTE.LastName = "Time";
PTE.HourlyRate = 60000;
PTE.PrintFullName();
Console.WriteLine("Salary: {0}", PTE.HourlyRate);
}
}
Pillars of OOPs:
1. Inheritance
2. Encapsulation
3. Abstraction
4. Polymorphism
Inheritance is one of the primary pillars of OOP.
It allows code reuse.
Code reuse can reduce time and errors.
Note: You will specify all the common fields, properties, methods in the base class, which allows
reusability. In the derived class you will only have fields, properties and methods, which are
specific to them.
Inheritance Syntax
1. In this example DerivedClass inherits from ParentClass.
2. C# supports only single class inheritance.
Part 23 - Polymorphism
Polymorphism is one of the primary pillars of OOP.
Polymorphism allows you to invoke derived class methods through a base class reference
during runtime.
In the base class the method is declared virtual, and in the derived class we override the
same method.
The virtual keyword indicates, the method can be overridden in any derived class.
using System; O/P:
public class Employee FN LN
{
FN LN - PartTime Employee
public string FName = "FN";
public string LName = "LN"; FN LN - FullTime Employee
public virtual void PrintFullName() FN LN - Temporary Employee
{
Console.WriteLine(FName + " " + LName);
}
}
public class PartTimeEmployee : Employee
{
public override void PrintFullName()
{
Console.WriteLine(FName + " " + LName + " - PartTime Employee");
}
}
public class FullTimeEmployee : Employee
{
public override void PrintFullName()
{
Console.WriteLine(FName + " " + LName + " - FullTime Employee");
}
}
public class TemporaryEmployee : Employee
{
public override void PrintFullName()
{
Console.WriteLine(FName + " " + LName + " - Temporary Employee");
}
}
class Program
{
public static void Main()
{
Employee[] arrEmp = new Employee[4];
arrEmp[0] = new Employee();
arrEmp[1] = new PartTimeEmployee();
arrEmp[2] = new FullTimeEmployee();
arrEmp[3] = new TemporaryEmployee();
}
}
Polymorphism simply means 'many forms'. After encapsulation and inheritance,
polymorphism plays a major role in object-oriented programming.
In other words, polymorphism means the states or behaviors of an object such as emotions
of a person.
Part 22 Encapsulation
Encapsulation is defined 'as the process of enclosing one or more items within a physical or
logical package'. Encapsulation, in object oriented programming methodology, prevents
access to implementation details.
Public
Private
Protected
Internal
Protected internal
Public Access Specifier
Public access specifier allows a class to expose its member variables and member functions to
other functions and objects. Any public member can be accessed from outside the class.
When the above code is compiled and executed, it produces the following result:
Length: 4.5
Width: 3.5
Area: 15.75
In the preceding example, the member variables length and width are declared public, so they
can be accessed from the function Main() using an instance of the Rectangle class, named r.
The member function Display() and GetArea() can also access these variables directly without
using any instance of the class.
The member functions Display() is also declared public, so it can also be accessed
from Main() using an instance of the Rectangle class, named r.
Private Access Specifier
Private access specifier allows a class to hide its member variables and member functions
from other functions and objects. Only functions of the same class can access its private
members. Even an instance of a class cannot access its private members.
In the preceding example, the member variables length and width are declaredprivate, so
they cannot be accessed from the function Main(). The member
functions AcceptDetails() and Display() can access these variables. Since the member
functions AcceptDetails() and Display() are declared public, they can be accessed
from Main() using an instance of the Rectangle class, named r.
Protected Access Specifier
Protected access specifier allows a child class to access the member variables and member
functions of its base class. This way it helps in implementing inheritance. We will discuss this
in more details in the inheritance chapter.
Internal Access Specifier
Internal access specifier allows a class to expose its member variables and member functions
to other functions and objects in the current assembly. In other words, any member with
internal access specifier can be accessed from any class or method defined within the
application in which the member is defined.
When the above code is compiled and executed, it produces the following result:
Length: 4.5
Width: 3.5
Area: 15.75
In the preceding example, notice that the member function GetArea() is not declared with any
access specifier. Then what would be the default access specifier of a class member if we don't
mention any? It is private.
Protected Internal Access Specifier
The protected internal access specifier allows a class to hide its member variables and
member functions from other class objects and functions, except a child class within the same
application. This is also used while implementing inheritance.
Note: If you want to know about the different kinds of method parameters, please watch Part 17- Method
parameters.
Part 27 Properties
In C# to encapsulate and protect fields we use properties
1. We use get and set accessors to implement properties.
2. A property with both get and set accessor is a Read/Write property.
3. A property with only get accessor is a Read only property.
4. A property with only set accessor is a Write only property.
Note: The advantage of properties over traditional Get() and Set() methods is that, you can
access them as if they were public fields.
using System;
public class Student
{
private int _Id;
private string _Name;
private int _PassMark = 35;
public int Id
{
set
{
if (value <= 0) { throw new Exception("Student Id should be greater than zero"); }
this._Id = value;
}
get { return _Id; }
}
public string Name
{
set
{
if (string.IsNullOrEmpty(value)) { throw new Exception("Name should be Null or Empty"); }
this._Name = value;
}
get { return string.IsNullOrEmpty(_Name) ? "No Name" : _Name; }
}
public int PassMark
{
get { return _PassMark; }
}
}
class Program
{
public static void Main()
{
Student objStudent = new Student();
objStudent.Id = 23; //objStudent.Id = -23;
objStudent.Name = "testing";//objStudent.Name = null;
Console.WriteLine("ID - {0}, Name - {1} and PassMark - {2}", objStudent.Id,
objStudent.Name,objStudent.PassMark);
}
} Output: ID - 23, Name - testing and PassMark 35
Part 28 Structs
Below way we will refactor the code,
using System;
public struct Customer
Just like classes, structs can have {
1. Private Fields private int _Id;
2. Public Properties private string _Name;
public int Id
3. Constructors {
4. Methods get { return this._Id; }
Object Initializer syntax, introduced in C# 3.0 set { this._Id = value; }
}
can be used to initialize either a struct or a
public string Name
class. {
get { return this._Name; }
set { this._Name = value; }
}
public Customer(int Id, string Name)
{
this._Id = Id;
this._Name = Name;
}
public void PrintDetails()
{
Console.WriteLine("ID: {0}, NAME: {1}", Id, Name);
}
}
class Program
Note: There are several differences between {
classes and structs which we will be looking public static void Main()
at in a later session {
Customer C1 = new Customer(101, "John");
C1.PrintDetails();
//Object Initializer syntax, introduced in C# 3.0
Customer C2 = new Customer();
C2.Id = 102;
C2.Name = "Mike";
C2.PrintDetails();
//Object Initializer syntax, introduced in C# 3.0
Customer C3 = new Customer { Id = 103, Name =
"Rosey"};
C3.PrintDetails();
}
}
Output:
ID: 101, NAME: John
ID: 102, NAME: Mike
ID: 103, NAME: Rosey
Note 1: A class or a struct cannot inherit Note 2: How do you a class from being
from another struct. Struct are sealed types. inherited? Or what is the significance of
sealed keyword?
Part 30 - Interfaces
We create interfaces using interface keyword. Just like classes interfaces also contains
properties, methods, delegates or events, but only declarations and no implementations.
1. Its a compile time error to provide implementations for any interface member.
2. Interface members are public by default, and they dont allow explicit access modifiers.
4. If class or a struct inherits from an interface, it must provide implementation for all
interface members. Otherwise, we get a compiler error.
5. A class or a struct can inherit from more than one interface at the same time, but
whereas, a class cannot inherit from more than once class at the same time.
6. Interfaces can inherit from other interfaces. A class that inherits this interface must
provide implementation for all interface members in the entire interface inheritance
chain.
using System;
interface ICustomer1
{
void Print1();
}
interface ICustomer2 : ICustomer1
{
void Print2();
}
public class Customer : ICustomer2
{
public void Print2()
{
Console.WriteLine("Print 2 Method");
}
public void Print1()
{
Console.WriteLine("Print 1 Method");
}
}
class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.Print1();
C1.Print2();
}
}
O/P
Print 1 Method
Print 2 Method
7. We cannot create an instance of an interface, but an interface reference variable can
point to derived class object.
Usually, Interface is incomplete, they dont have any implementation. Thats why the C#
language doesnt allow to create instance of an interface
If a class inherits an abstract class, there are 2 options available for that class
Option 1: Provide Implementation for all the abstract members inherited from the base abstract
class.
Option 2: If the class does not wish to provide Implementation for all the abstract members
inherited from the abstract class, then the class has to be marker as abstract.
Abstract Interface
1. Abstract class can have 1. Interface cant have implementation
implementations for some of its for any of its members,
members (Methods).
3. Abstract class can inherit from another 3. An interface can inherit from another
abstract class or another interface. interface only and cannot inherit from
an abstract class
4. A class cannot inherit from multiple 4. A class can inherit from multiple
abstract class at the same time. interfaces at the same time.
5. Abstract class members can have 5. Interface members cannot have
access modifier. access modifier.
Part 36 - Delegates
A delegate is a type safe function pointer. That is, it holds a reference (Pointer) to a function.
The signature of the delegate must match the signature of the function, the delegate points to,
otherwise you get a complier error. This is the reason delegates are called as type safe function
pointers.
A Delegate is similar to a class. You can create an instance of it, and when you do so, you pass
in the function name as a parameter to the delegate constructor, and it is to this function the
delegate will point to.
using System;
public delegate void HelloFunctionDelegate(string Message);
public class Program
{
public static void Hello(string strMessage)
{
Console.WriteLine(strMessage);
}
public static void Main()
{ //A Delegate is a type safe function pointer
HelloFunctionDelegate del = new HelloFunctionDelegate(Hello);
del("Hello Delegate Mthd");
}
}
O/P: Hello Delegate Mthd
Tip to remember delegate syntax: Delegates syntax look very much similar to a method with the
delegate keyword.
Part 37 - Delegates usage
using System;
using System.Collections.Generic;
class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public int Experience { get; set; }
public static void PromotedEmployee(List<Employee> EmployeeList)
{
foreach(Employee emp in EmployeeList)
{
if (emp.Experience >= 5) Console.WriteLine(emp.Name + " " + "Promoted");
}
}
}
public class Program
{
public static void Main()
{
List<Employee> e = new List<Employee>();
e.Add(new Employee { ID = 101, Name = "Mark", Salary = 2000, Experience = 5 });
e.Add(new Employee { ID = 102, Name = "Nike", Salary = 4000, Experience = 4 });
e.Add(new Employee { ID = 103, Name = "Rose", Salary = 3000, Experience = 3 });
e.Add(new Employee { ID = 104, Name = "Nancy", Salary = 6000, Experience = 6 });
e.Add(new Employee { ID = 105, Name = "Mary", Salary = 7000, Experience = 7 });
Employee.PromotedEmployee(e);
}
}O/P:Mark Promoted
Nancy Promoted
Mary Promoted
Note: A multicast delegate invokes the methods in the invocation list, in the same order in which
they are added.
If the delegate has a return type other than void and if the delegate is a multicast delegate,
only the value of the last invoked method will be returned. Along the same lines, if the delegate
has an out parameter, the value of the output parameter, will be the value assigned by the last
method.
Common interview question Where do you use multicast delegates?
Multicast delegate makes implementation of observer design pattern very simple. Observer
pattern is also called as publish/subscribe pattern.
using System;
public delegate void MDeleg(); using System;
class Program public delegate void MDeleg();
{ class Program
public static void Main() {
{ public static void Main()
MDeleg Q1, Q2, Q3, Q4; {
Q1 = new MDeleg(SelectedOne); MDeleg Q1 = new MDeleg(SelectedOne);
Q2 = new MDeleg(SelectedTwo); Q1 += SelectedTwo;
Q3 = new MDeleg(SelectedThree); Q1 += SelectedThree;
Q4 = Q1 + Q2 + Q3 - Q1; Q1 -= SelectedTwo;
Q4(); Q1();
} }
public static void SelectedOne() public static void SelectedOne()
{ {
Console.WriteLine("SelectedOne Called"); Console.WriteLine("SelectedOne Called");
} }
public static void SelectedTwo() public static void SelectedTwo()
{ {
Console.WriteLine("SelectedTwo Called"); Console.WriteLine("SelectedTwo Called");
} }
public static void SelectedThree() public static void SelectedThree()
{ {
Console.WriteLine("SelectedThree Called"); Console.WriteLine("SelectedThree Called");
} }
} }
O/P: O/P:
SelectedTwo Called SelectedOne Called
SelectedThree Called SelectedThree Called
Used input and Output parameter
using System;
using System; public delegate void MDeleg(out int Value);
public delegate int MDeleg(); class Program
class Program {
{ public static void Main()
public static void Main() {
{ MDeleg Q1 = new MDeleg(SelectedOne);
MDeleg Q1 = new MDeleg(SelectedOne); Q1 += SelectedTwo;
Q1 += SelectedTwo; Q1 -= SelectedThree;
Q1 += SelectedThree; int OutputreturnVal = -1;
int returnVal = Q1(); Q1(out OutputreturnVal);
Console.WriteLine("RV: {0}", returnVal); Console.WriteLine("OutVal: {0}",
} OutputreturnVal);
public static int SelectedOne() }
{ public static void SelectedOne(out int Value)
return 1; {
} Value = 1;
public static int SelectedTwo() }
{ public static void SelectedTwo(out int Value)
return 2; {
} Value = 2;
public static int SelectedThree() }
{ public static void SelectedThree(out int Value)
return 3; {
} Value = 3;
} }
O/P: }O/P:
RV: 3. . . OutVal: 2
Showing actual unhandled exceptions to the end user is bad for two reasons
1. Users will be annoyed as they are cryptic and does not make sense to the end users.
2. Exceptions contain information, which can be used for hacking into your application.
An exception is actually a class that derives from System.Exception class. The System.Exception
class has several useful properties, which provide valuable information about the exception.
Message: Gets a message that describes the current exception.
Stack Trace: Provides the call stack to the line number in the method where the exception
occurred.
using System;
using System.IO;
class ExceptionHandle
{
public static void Main()
{
StreamReader strReader = null;
try
{ //@ - Verbatim String Literal. It means that escaping isn't applied.
strReader = new StreamReader(@"C:\Users\sathys\Desktop\sa.txt");
Console.WriteLine(strReader.ReadToEnd());
}
catch(FileNotFoundException exFile)
{
Console.WriteLine("File '{0}' is not found", exFile.FileName);
}
catch(Exception ex) //Exception should be always @ last or else will get compiler error
{
Console.WriteLine(ex.Message);
}
/* though the 'finally' is optional but if we are not use it. Incase if
we get any exception in 'catch' that time the strReader shouldn't close*/
finally
{
if (strReader != null) strReader.Close();
}
}
}
O/P:<<<if we pass correct filename then the result should be read the text from the file>>>
Could not find a part of the path 'C:\Users\sathys\Desktop\sa.txt'.
Releasing System Resources
We use try, catch and finally blocks for exception handling.
try The codes that can possible cause an exception will be in the try block.
catch Handles the exception.
finally Clean and free resources that the class was holding onto during the program execution.
Finally block is optional.
Note: It is a good practice to always release resources in the finally block, because finally block
is guaranteed to execute, irrespective of whether there is an exception or not.
Specific exceptions will be caught before the base general exception, so specific exception
blocks should always be on top of the base exception block. Otherwise, you will encounter a
complier error.
Note: It is also possible to provide your own custom serialization, which will discuss In a later
session.
If a program uses set of integral numbers, consider replacing them with enums. Otherwise the
program becomes less
Readable
Maintainable
In the next session we will replace, these integral numbers with enums, which makes the program
better readable and maintainable.
using System;
class Program
{
public static void Main()
using System; {
class Program Customer[] cus = new Customer[3];
{ cus[0]=new Customer{Name="Mark",Gender=Gender.Male};
public static void Main() cus[1]=new Customer{Name="Mary",Gender=Gender.Female};
{ cus[2]=new Customer{Name="Jessy",Gender=Gender.Unknown};
Customer[] cus = new Customer[3]; foreach (Customer cs in cus)
cus[0] = new Customer {Name="Mark",Gender=0}; {
cus[1] = new Customer {Name="Mary",Gender=1}; Console.WriteLine("Name: {0}, Gender: {1}",
cus[2] = new Customer {Name="Jessy",Gender=2}; cs.Name, getGender(cs.Gender));
foreach (Customer cs in cus) }
{ }
Console.WriteLine("Name: {0}, Gender: {1}", public static string getGender(Gender gender)
cs.Name, getGender(cs.Gender)); { //0 - Male, 1 - Female, 2 - Unknown
} switch (gender)
} {
public static string getGender(int intGender) case Gender.Male: return "Male";
{ //0 - Male, 1 - Female, 2 - case Gender.Female: return "Female";
Unknown case Gender.Unknown: return "Unknown";
switch (intGender) default: return "Not Declare";
{ }
case 0: return "Male"; }
case 1: return "Female"; }
case 2: return "Unknown"; public enum Gender
default: return "Not Declare"; {
} Male,
} Female,
} Unknown
class Customer }
{ class Customer
public string Name { get; set; } {
public int Gender { get; set; } public string Name { get; set; }
} public Gender Gender { get; set; }
O/P: Name: Mark, Gender: Male }O/P: Name: Mark, Gender: Male
Name: Mary, Gender: Female Name: Mary, Gender: Female
Name: Jessy, Gender: Unknown Name: Jessy, Gender: Unknown
Part 47 Enums
In a program uses set of integral numbers, consider replacing them with enums, which makes
the program more
Readable
Maintainable
1. Enums are enumerations.
2. Enums are strongly typed constants. Hence, an explicit cast is needed to convert from enum
type to an integral type and vice versa. Also, an enum of one type cannot be implicitly
assigned to an enum of another type even though the underlying values of their members
are the same.
#region Properties
public int ID { get { return _id; } set { _id = value; } }
public string FirstName { get { return _firstName; } set { _firstName = value; } }
public string LastName { get { return _lastName; } set { _lastName = value; } }
#endregion
#region Method
public string GetFullName()
{
return this.FirstName + " - " + this.LastName;
}
#endregion
}
In c# there are 5 different access modifiers:
1. Private
2. Protected
3. Internal
4. Protected Internal
5. Public
Note: Using regions you can expand and collapse sections of your code either manually, or
using visual studio Edit Outlining Toggle All Outlining
TYPE TYPE MEMBERS
1. In this example - Customer in the Type 1. In this example - Fields, Properties and
Method are Type Members
2. In general classes, struct, enum, 2. Fields, properties, constructors,
interfaces and delegates are called as methods, etc., that normally reside in a
Type type are called as type members.
3. Types can have only 2 (internal, public) 3. Type Members can have all the access
of the 5 access modifiers modifiers
4. Default access modifier - internal 4. Default access modifier - private
Protected Internal members can be accessed by any code in the assembly in which it is
declared, or from within a derived class in another assembly. It is a combination of protected
and internal. If you have understood protected and internal, this should be very easy to follow.
Part 51 - Access Modifiers for types
You can use all the 5 access modifiers with type members, but a types allows only internal and
public access modifiers. It is a compile time error to use private, protected and protected
internal access modifiers with types.
Part 52 - Attributes
Attributes allow you to add declarative information to your programs. This information can then
be queried at runtime using reflection.
There are several Pre-defined Attributes provided by .NET. It is also possible to create your own
Custom Attributes.
I am waiting for updates. Please share me if you get any response from the customer.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int Sum = Calculator.Add(new List<int> { 5, 6 });
Console.WriteLine(Sum);
int Sum1 = Calculator.Add(5, 6); //Warning CS0618 'Calculator.Add(int, int)' is obsolete: 'Use [
Add(List<int> numbers) ] Method'
}
}
public class Calculator
{
//Obsolete is referred to the class 'ObsoleteAttribute'.But Attribute is optional we can directly use Obsolete
[Obsolete("Use [ Add(List<int> numbers) ] Method") ]
public static int Add(int FN, int SN)
{
return FN + SN;
}
public static int Add(List<int> numbers)
{
int sum = 0;
foreach (int Number in numbers) { sum = sum + Number; }
return sum;
}
} O/P: 11
Part 53 - Reflection
Reflection is the ability of inspecting an assemblies metadata at runtime. It is used to find all
types in an assembly and/or dynamically invoke methods in an assembly.
Uses of reflection:
1. When you drag and drop a button on a win forms or an asp.net application. The
properties window uses reflection to show all the properties of the Button class. So,
reflection extensively used by IDE or a UI designers.
2. Late binding can be achieved by using reflection. You can use reflection to dynamically
create an instance of a type, about which we dont have any information at compile
time. So, reflection enables you to use code that is not available at compile time.
3. Consider an example where we have two alternate implementations of an interface.
You want to allow the user to pick one or the other using a config file. With reflection, you
can simply read the name of the class whose implementation you want to use from the
config file, and instantiate an instance of that class. This is another example for late
binding using reflection.
using System;
using System.Reflection;
namespace Program
{
public class MainClass
{
public static void Main()
{ //3 ways we will get type of 'Customer'
Type T = Type.GetType("Program.Customer");//WAY 1
//Type T = typeof(Customer); //WAY 2
//Customer C1 = new Customer(); //WAY 3
//Type T = C1.GetType();
Console.WriteLine(T.FullName);
Console.WriteLine();//Get Property List
Console.WriteLine("Get the properties list in the Program");
PropertyInfo[] properties = T.GetProperties();
foreach (PropertyInfo property in properties) { Console.WriteLine(property.PropertyType.Name +
" - " + property.Name); }
Console.WriteLine();//Get Method List
Console.WriteLine("Get the Methods list in the Program");
MethodInfo[] methods = T.GetMethods();
foreach (MethodInfo method in methods) { Console.WriteLine(method.ReturnType + " - " +
method.Name); }
Console.WriteLine();//Get Constructor List
Console.WriteLine("Get the Constructors list in the Program");
ConstructorInfo[] constructors = T.GetConstructors();
foreach (ConstructorInfo constructor in constructors) {
Console.WriteLine(constructor.ToString() + " - " + constructor.Name); }
}
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public Customer() { this.ID = -1; this.Name = string.Empty; }
public Customer(int _id, string _name) { this.ID = _id; this.Name = _name; }
public void PrintMtd()
{
Console.WriteLine("Name: {0}", this.Name);
}
}
}
O/P: Program.Customer
Part 56 Generics
Generics are introduced in C# 2.0. Generics allow us to design classes and methods decoupled
from the data types. Generic classes are extensively used by collection classes available in
System.Collections.Generic namespace. (Covered in the next session)
One way of making AreEqual() method reusable, is to use object type parameters. Since, every
type in .NET directly or indirectly inherit from System.Object type, AreEqual() method works with
any data type, but the problem is performance degradation due to boxing and unboxing
happening.
Also, AreEqual() method is no longer type safe. It is now possible to pass integer for the first
parameter, and a string for the second parameter. It doesn't really make sense to compare
strings with integers.
At the point, when the client aide wants to invoke this method, they need to specify the type;
they want the method to operate on. If the user wants the AreEqual() method to work with
integers, they can invoke the method specifying int as the datatype using angular brackets as
shown below. bool Equal = CaIculator.AreEqual<int>(2, 1);
In this example, we made the method generic. Along the same lines, it is also possible to make
classes, interfaces and delegates generic.
Present in the namespace - using System; Present in the namespace - using System.Text;
string s = string.Empty; StringBuilder sb = new StringBuilder();
for (i = 0; i < 1000; i++) { for (i = 0; i < 1000; i++) {
s += i.ToString() + " "; sb.Append(i);
} sb.Append(' ');}
You'll end up creating 2001 strings here, This should place much less stress on the memory
2000 of which are thrown away. allocator.
using System; using System;
namespace Program using System.Text;
{ namespace Program
public class MainClass {
{ public class MainClass
public static void Main() {
{ public static void Main()
string userString = "C#"; {
userString += " Videos"; StringBuilder userString = new StringBuilder("C#");
userString += " Tutorial"; userString.Append(" Videos");
userString += " for"; userString.Append(" Tutorial");
userString += " beginners"; userString.Append(" for");
Console.WriteLine(userString); userString.Append(" beginners");
} Console.WriteLine(userString);
} }
}O/P: C# Videos Tutorial for beginners }
}O/P: C# Videos Tutorial for beginners
Part 61 - Partial classes
Partial classes allow us to split a class into 2 or more files. All these parts are then combined into a
single class, when the application is compiled. The partial keyword can also be used to split a
struct or an interface over two or more files.
Advantages of partial classes
1. The main advantage is that, visual studio uses partial classes to separate, automatically
generated system code from the developer1s code. For example, when you add a
webform, two .CS files are generated
a) WebForm1.aspx.cs- Contains the developer code
b) WebForm1.aspx.designer.cs- Contains the system generated code. For example,
declarations for the controls that you drag and drop on the webform.
2. When working on large projects, spreading a class over separate files allows multiple
programmers to work on t simultaneously. Though, Microsoft claims this as an
advantage, I havent really seen anywhere, people using partial classes, just to work on
them simultaneously.
2. All the parts spread across different files, must have the same access modifiers.
3. If any of the parts are declared abstract, then the entire type is considered abstract.
4. If any of the parts are declared sealed, then the entire type is considered sealed.
5. If any of the parts inherit a class, then the entire type inherits that class.
6. C# does not support multiple class inheritance. Different parts of the partial class must
not specify different base classes.
7. Different parts of the partial class can specify different base interfaces, and the final type
implements all of the interfaces listed by all of the partial declarations.
8. Any members that are declared in a partial definition are available to all of the other
parts of the partial class.
6. It is a compile time error, to include declaration and implementation at the same time for
a partial method.
7. A partial method return type must be void. Including any other return type is a compile
time error.
8. Signature of the partial method declaration, must match with the signature of the
implementation.
9. A partial method must be declared within a partial class or partial struct. A non-partial
class or struct cannot include partial methods.
10. A partial method can be implementation only once. Trying to implement a partial
method more than once, raises a compile time error.
Another example of indexers usage in .NET. To retrieve data from a specific column
when looping thru Sq1DataReader object, we can use either the integral indexer or
string indexer.
namespace WebApplication
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (Sq1Connection con = new Sq1Connection(CS))
{
Sq1Command cmd = new Sq1Command("Select * from tblEmployee", con);
con.Open();
Sq1DataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// Using integral indexer to retrieve Id column value
Response.Write("Id = " + rdr[0].ToString() + " ");
// Using string indexer to retrieve Id column value
Response.Write("Name = " + rdr["Name"].ToString());
Response.Write("<br/>");
}
}
}
}
Web.config
<connectionStrings>
<add name="DBCS" connectionString="data source=.;database=Sample;Integrated Security=SSPI"
providerName="System.Data.SqlClient"/>
</connectionStrings>
Right click on SqlDataReader class, to view its metadata. Notice that, there is an integral and
string indexer defined.
Part 65 - Indexers
Part 66 - Overloading indexers
You can also explicitly specify the Input type but not required
Employee employee = listEmployees.Find(Employee Emp) => Emp.ID == 102);
=> is called lambda operator and read as GOES TO. Notice that with Lambda expression you don't have
to use the delegate keyword explicitly and don't have to specify the input parameter type explicitly. The
parameter type is inferred. Lambda expressions are more convenient to use than anonymous methods.
Lambda expressions are particularly helpful for writing LINQ query expressions.
Multithreading
A thread is defined as the execution path of a program. Each thread defines a unique flow of
control. If your application involves complicated and time consuming operations, then it is
often helpful to set different execution paths or threads, with each thread performing a
particular job.
Threads are lightweight processes. One common example of use of thread is implementation
of concurrent programming by modern operating systems. Use of threads saves wastage of
CPU cycle and increase efficiency of an application.
So far we wrote the programs where a single thread runs as a single process which is the
running instance of the application. However, this way the application can perform one job at
a time. To make it execute more than one task at a time, it could be divided into smaller
threads.
namespace MultithreadingApplication
{
class MainThreadProgram
{
static void Main(string[] args)
{
Thread th = Thread.CurrentThread;
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result:
This is MainThread
CurrentPrinciple Gets or sets the thread's current principal (for role-based security).
CurrentUICulture Gets or sets the current culture used by the Resource Manager to look up
culture-specific resources at run-time.
IsAlive Gets a value indicating the execution status of the current thread.
IsThreadPoolThread Gets a value indicating whether or not a thread belongs to the managed
thread pool.
The following table shows some of the most commonly used methods of theThread class:
Sr.No. Methods
Creating Threads
Threads are created by extending the Thread class. The extended Thread class then calls
the Start() method to begin the child thread execution.
The following program demonstrates the concept:
using System;
using System.Threading;
namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
}
When the above code is compiled and executed, it produces the following result:
In Main: Creating the Child thread
Child thread starts
Managing Threads
The Thread class provides various methods for managing threads.
The following example demonstrates the use of the sleep() method for making a thread pause
for a specific period of time.
using System;
using System.Threading;
namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
When the above code is compiled and executed, it produces the following result:
In Main: Creating the Child thread
Child thread starts
Child Thread Paused for 5 seconds
Child thread resumes
Destroying Threads
The Abort() method is used for destroying threads.
The runtime aborts the thread by throwing a ThreadAbortException. This exception cannot be
caught, the control is sent to the finally block, if any.
The following program illustrates this:
using System;
using System.Threading;
namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread()
{
try
{
Console.WriteLine("Child thread starts");
catch (ThreadAbortException e)
{
Console.WriteLine("Thread Abort Exception");
}
finally
{
Console.WriteLine("Couldn't catch the Thread Exception");
}
}
childThread.Abort();
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result:
In Main: Creating the Child thread
Child thread starts
0
1
2
In Main: Aborting the Child thread
Thread Abort Exception
Couldn't catch the Thread Exception