You are on page 1of 75

C-Sharp

Access Modifiers:
Access modifiers are keywords added to the class, struct, or member declaration to
specify restrictions, so that only the program or namespace they are declared in may use them.
Types of Access Modifiers:

a. Public
b. Private
c. Internal
d. Protected
e. ProtectedInternal

namespace Exp
{
public class Class1
{
public int a = 0;private int b = 1;protected int c = 2 ;
internal int d = 3;protected internal int e = 4;
}
public class test
{
public void x()
{
Class1 c = new Class1();
c.{a,d,e} //{b,c}private and protected are not accessible
test t = new test();
t. // Nothing is accessible

}
}
}
//////////////////////////////////////////////
namespace Exp
{
public class Class1
{
public int a = 0; private int b = 1;protected int c = 2 ;
internal int d = 3; protected internal int e = 4;
}
public class test:Class1 //if inherited
{
public void x()
{
Class1 c = new Class1();
c.{a,d,e} //private and protected are not accessible
test t = new test();
t.{a,c,d,e} // {b}private is not accessible
}
}
}
/////////////////////////////////////////////////////
using Exp; // adding as reference

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Exp.Class1 c = new Class1();
c.a ;//public alone is accessible
Program p = new Program();
p.//nothing is accessible
}
}
}
////////////////////////////////////////////////////////////

using Exp; // adding as reference

namespace ConsoleApplication1
{
class Program:Class1 //if inherited
{
static void Main(string[] args)
{
Exp.Class1 c = new Class1();
c.a ;//public alone is accessible
Program p = new Program();
p.{a,c,e} //public,protected,protected internal are accessible
//private and internal are not accessible
}
}
}

//////////////////////////////////////////////////////////

Public: No restriction level can be accessed anywhere.

Example:
public class First // public class
{
public int x=5; // public variable
}
public class Second
{
static void Main()
{
First f=new First();
f.x = 6; // Can be accessed even without inheriting
}
}

Private: Accessible to current class only.


Example
public class First // public class
{
private int x=5; // private variable
}
public class Second
{
static void Main()
{
First f=new First();
f. // x Cannot be accessed
}
}

Protected: Accessible to current class and all derived classes even in other application.

Example

public class First // public class


{
protected int x=5; // protected variable
}
public class Second : First
{
static void Main()
{
First f=new First();
f. // x Cannot be accessed by its own object(Base class object)
Second s=new Second();
s.x=6; // Can be accessed by derived class object

}
}

Internal: Accessible to any class in the current assembly or DLL. That is if another program which is
adding main program’s DLL as reference and tries to access its variables or members, only elements
having public access are accessible but not Internal or others

Protected Internal: Protected Internal may be accessed only by a derived class that's contained
in the other application or any class in its same assembly. You use protected internal in situations
where you want to deny access to parts of a class functionality to any descendant classes found
in other applications which does not inherit this class.
Access limited to this program or types derived from the containing class".
Important points to be noted with Access modifiers

1. Namespaces cannot have access modifiers. They are always public. So


public namespace Namespace { } Will produce compile time error

2. Individual classes can be either public or internal but not protected or private. So

Private class NewClass {} will produce a compile-time error. By default, classes are
internal. By default, methods and variables in class are private

3. Interfaces, like classes can be either public or internal but not protected or private.

4. Methods declared inside interfaces cannot have access modifiers.

5. Enums are always public. They cannot have access modifiers either.

6. We cannot give access modifiers for variables inside a method

7. Derived classes can either have the same restriction level or can be more restrictive than the
base class but not less restrictive. So

internal class Base { }

Public class Child : Base { } will produce a compile-time error.

8. Nested classes can have any access modifier.(classes inside other class)

namespace ConsoleApplication4 {
public class A
{
protected int b = 7;
internal int c = 1;
public int d = 2;

internal class B {
public int x = 3;
int y = 5;
}

protected class C {
public int z = 4;
}
}
class E:A
{
E e = new E();
A a = new A();
void main()
{
//e.{b,c,d } are accessible but not x,y or z

a.c = 5;
a.d = 6;

A.B ab = new B(); // Way to access Nested class


ab.x = 4; // but y is not accessible because of private modifier

A.C ac = new A.C();// Way to access Nested class


ac.z = 5;
}
}

Keywords:
Method Definitions:

• virtual: Method may be overridden


• abstract: Method must be overridden in nonabstract derived classes (only permitted in
abstract classes)
• override: Method overrides a base class method (must be used if a method is being
overridden)
• extern: Method definition is found elsewhere

Override example

public class MyBaseClass


{
public virtual void DoSomething()
{
// Base implementation.
}
}
public class MyDerivedClass2 : MyBaseClass
{
public override void DoSomething()
{
// Derived class implementation, overrides base implementation.
}
}

If override is used, then sealed may also be used to specify that no further modifications can be
made to this method in derived classes, that is, this method can't be overridden by derived
classes.
public class MyDerivedClass : MyBaseClass
{
public override sealed void DoSomething()
{
// Derived class implementation, overrides base implementation.
}
}

Abstract Class and Interface Example:

namespace ConsoleApplication1
{
public abstract class absClass // This is an abstract class
{
public void nonabsmethod() // nonabstract method which is defined
{
Console.WriteLine("This is Non Abstract Method Definition");
}
public abstract void absmethod (); //method to be defined in derived class
}
interface myinterface
{
void method();
}
interface myinterface2
{
void method2();
}

public class MainClass : absClass, myinterface, myinterface2 //abstract class


should be derived first followed by interfaces
{
void myinterface.method() //Interface myinterface method definition
{
Console.WriteLine("This is Interface Definition");
}
void myinterface2.method2()//Interface myinterface2 method definition
{
Console.WriteLine("This is Interface2 Definition");
}
public override void absmethod () //abstract method definition
{
Console.WriteLine("This is Abstract Method Definition");
}
public static void Main()
{
myinterface MI = new MainClass();
myinterface2 MI2 = new MainClass();
MI.method(); //calling interface method
MI2.method2(); //calling interface method
MainClass MC = new MainClass();
MC.nonabsmethod (); //calling nonabstract method
MC.absmethod (); //calling abstract method
}
}
}
Const: The const keyword is used to specify that the value of the field or the local variable is
constant, which means it cannot be modified.

Ex: const int x = 0;

Public const double gravitational = 6.673e-11;


Private const string product = "Visual C#";

A constant expression is an expression that can be fully evaluated at compile time. Therefore, the
only possible values for constants of reference types are string and null.

The constant declaration can declare multiple constants, such as:

Public const double x = 1.0, y = 2.0, z = 3.0;

The static modifier is not allowed in a constant declaration.

A constant can participate in a constant expression, as follows:

Public const int c1 = 5;


Public const int c2 = c1 + 100;

Readonly: The readonly keyword is a modifier that can be used on fields or variables. When a field
declaration includes a readonly modifier, assignments (initialization) to the fields can only occur in
the declaration or in a constructor in the same class.

Ex:
Public readonly int y = 5;

class Dog
{
readonly int x = 5;
readonly int y;
readonly int z;
public Dog() //Constructor
{
y = 6; // Initializing is accepted
}
static void Main()
{
z = 7; // Not possible-causes compile time error
}
}
The readonly keyword is different from the const keyword. A const field can only be initialized at the
declaration of the field. A readonly field can be initialized either at the declaration or in a constructor.
Therefore, readonly fields can have different values depending on the constructor used. Also, while a
const field is a compile-time constant, the readonly field can be used for runtime constants as in the
following example:

Public static readonly uint x = (uint)DateTime.Now.Ticks;


Ex:
public class ReadOnlyTest
{
class SampleClass
{
public int x;
public readonly int y = 25; // Declare a readonly field
public readonly int z;

public SampleClass()
{
z = 24; // Initialize a readonly instance field
}

public SampleClass(int p1, int p2, int p3)


{
x = p1;
y = p2;
z = p3;
}
}
static void Main() {
SampleClass p1 = new SampleClass(11, 21, 32); // OK
Console.WriteLine("p1: x={0}, y={1}, z={2}", p1.x, p1.y, p1.z);
SampleClass p2 = new SampleClass();
p2.x = 55; // OK
Console.WriteLine("p2: x={0}, y={1}, z={2}", p2.x, p2.y, p2.z);
Console.ReadKey();
}
}

Output
p1: x=11, y=21, z=32
p2: x=55, y=25, z=24
Comments
In the preceding example, if you use a statement like this:
p2.y = 66; // Error you will get the compiler error message:

Checked and UnChecked


Checked keyword throws an error if the value converted does not fit into the type while explicit
conversion.
byte destinationVar;
short sourceVar = 281;
destinationVar = checked((byte)sourceVar);
Console.WriteLine("sourceVar val: {0}", sourceVar);
Console.WriteLine("destinationVar val: {0}", destinationVar);
Console.ReadKey();

This program causes runtime error at line3.


UnChecked keyword tries to reduce the value,so as to fit into the variable of particular type
and does not cause error.

byte destinationVar;
short sourceVar = 281;
destinationVar = unchecked((byte)sourceVar);
Console.WriteLine("sourceVar val: {0}", sourceVar);
Console.WriteLine("destinationVar val: {0}", destinationVar);
Console.ReadKey();

Output:
sourceVar val: 281
destinationVar val: 25

Static: static modifier is used to declare a static member, which belongs to the type itself
rather than to a specific object, which means it cannot be accessed through any other object. The
static modifier can be used with classes, fields, methods, properties, operators, events and
constructors, but cannot be used with indexers, destructors, or types other than classes
Ex:
Public class Base

Public struct Structure

Public static int x = 100;

To refer to the static member x, use the fully qualified name (unless it is accessible from the
same scope):

Base.Structure.x

Static Classes
A class can be declared static, indicating that it contains only static members. It is not possible to
create instances of a static class using the new keyword. Static classes are loaded automatically
by the .NET Framework common language runtime (CLR) when the program or namespace
containing the class is loaded.

The main features of a static class are:


• They only contain static members and static fields.
• They cannot be instantiated.
• They are sealed.
• They cannot contain Instance Constructors.
• While an instance of a class contains a separate copy of all instance fields of the class
there is only one copy of each static field.
• It is not possible to use this to reference static methods or property accessors
• Static classes cannot contain a constructor, although it is still possible to declare a static
constructor to assign initial values or set up some static state
• A static class can make your implementation simpler and faster because you do not have
to create an object in order to call its methods

Static class CompanyInfo


{
Public static string GetCompanyName ()
{
return "CompanyName";
}
Public static string GetCompanyAddress ()
{
return "CompanyAddress";
} //...
}

Static Members
A static method, field, property, or event is callable on a class even when no instance of the class
has been created. If any instances of the class are created, they cannot be used to access the
static member. Only one copy of static fields and events exists, and static methods and
properties can only access static fields and static events. Static members are often used to
represent data or calculations that do not change in response to object state; for instance, a
math library might contain static methods for calculating sine and cosine.

Static class members are declared using the static keyword before the return type of the
member, for example:

Public class Automobile


{
Public static int NumberOfWheels = 4;
Public static int SizeOfGasTank
{
Get {return 15 ;}
}
Public static void Drive ()
{}
Public static event EventType RunOutOfGas; //other non-static fields
}
Static members are initialized before the static member is accessed for the first time, and before
the static constructor, if any is called. To access a static class member, use the name of the class
instead of a variable name to specify the location of the member. For example:

Automobile.Drive (); int i = Automobile.NumberOfWheels;

Static members can access only static fields .Whereas non static methods can
access both static and non static fields.
class x
{
public int w = 7;
static int e = 9;
static void method()
{
e = 5;
w = 7; // Not allowed
}
void method2()
{
w = 10;
e = 10;
}
static void Main()
{
}
}

Constructor in C#:
Broadly speaking, it is a method in the class which gets executed when its object is
created. Usually we put the initialization code in the constructor. Constructors cannot have a
return type. Writing a constructor in the class is damn simple, have a look at the following
sample :

public class mySampleClass


{
public mySampleClass()
{
// This is the constructor method.
}
// rest of the class members goes here.
}

When the object of this class is instantiated the constructor will be executed. Something like
this:
mySampleClass obj = new mySampleClass()
// At this time the code in the constructor will be executed

Constructor Overloading: C# supports overloading of constructors, which means we can have


constructors with different set of parameters. So our class can be like this:

public class mySampleClass


{
public mySampleClass()
{
// This is the no parameter constructor method.
// First Constructor
}
public mySampleClass(int Age)
{
// This is the constructor with one parameter.
// Second Constructor
}
public mySampleClass(int Age, string Name)
{
// This is the constructor with two parameters.
// Third Constructor
}
// rest of the class members goes here.
}

The call to the constructor now depends on the way you instantiate the object. For example:

mySampleClass obj = new mySampleClass()


// At this time the code of no parameter constructor
(First Constructor)will be executed

mySampleClass obj = new mySampleClass(12)


// At this time the code of one parameter constructor
(Second Constructor)will be executed.

The call to the constructors is completely governed by the rules of the overloading here.

Calling Constructor from another Constructor: You can always make the call to one
constructor from within the other. Say for example:

public mySampleClass()
{
mySampleClass(10) //or public mySampleClass(): this(10)
// This is the no parameter constructor method.
// First Constructor
}
Here if I instantiate the object as
mySampleClass obj = new mySampleClass ();

Then the code of public mySampleClass (int Age) will be executed before the code of
mySampleClass ().

*Note that only this and base keywords are allowed in initializers, other method calls will raise
the error.

Constructors in Inheritance: Let us first create the inherited class.

public class myBaseClass


{
public myBaseClass()
{
// Code for First Base class Constructor
}
public myBaseClass(int Age)
{
// Code for Second Base class Constructor
}
// Other class members goes here
}

public class myDerivedClass : myBaseClass // inheriting the class here.


{
public myDerivedClass()
{
// Code for the First myDerivedClass Constructor.
}
public myDerivedClass(int Age):base(Age)
{
// Code for the Second myDerivedClass Constructor.
}
// Other class members goes here
}

The execution sequence, if we create the object of the Derived class as


myDerivedClass obj = new myDerivedClass()

Then the sequence of execution will be


1. Public myBaseClass () method.
2. Public myDerivedClass () method.

The execution sequence, if we create the object of the Derived class as

myDerivedClass obj = new myDerivedClass (15)

Then the sequence of execution will be


1. Public myBaseClass (int Age) method.
2. Public myDerivedClass (int Age) method.

Here the new keyword base has come into picture. This refers to the base class of the current
class. So, here it refers to the myBaseClass. And base(10) refers to the call to myBaseClass(int
Age) method.

Static Constructors:
This is a special constructor and gets called before the first object of the class is created. The
time of execution cannot be determined, but it is definitely before the first object creation - could
be at the time of loading the assembly.

public class myClass


{
static myClass()
{
// Initialization code goes here.
// Can only access static members here.
}
// Other class methods goes here
}

Notes for Static Constructors:


1. There can be only one static constructor in the class.
2. The static constructor should be without parameters.
3. It can only access the static members of the class.
4. There should be no access modifier in static constructor definition.

Ok fine, all the above points are fine but why is it like that? Let us go step by step here.

Firstly, the call to the static method is made by the CLR and not by the object, so we do not need
to have the access modifier to it.

Secondly, it is going to be called by CLR, who can pass the parameters to it, if required, No one,
so we cannot have parameterized static constructor.

Thirdly, Non-static members in the class are specific to the object instance so static constructor,
if allowed to work on non-static members, will reflect the changes in all the object instances,
which is impractical. So static constructor can access only static members of the class.
Fourthly, Overloading needs the two methods to be different in terms to methods definition,
which you cannot do with Static Constructors, so you can have at the most one static constructor
in the class.

Now, one question raises here, can we have the two constructors as

public class myClass


{
static myClass()
{
// Initialization code goes here.
// Can only access static members here.
}
public myClass()
{
// Code for the First myDerivedClass Constructor.
}
// Other class methods goes here
}
This is perfectly valid, though doesn’t seem to be in accordance with overloading concepts. But
why? Because the time of execution of the two method are different. One is at the time of loading
the assembly and one is at the time of object creation.

FAQs regarding Constructors:

1. Is the Constructor mandatory for the class?


Yes, It is mandatory to have the constructor in the class and that too should be accessible for the
object i.e., it should have a proper access modifier. Say for example While Inheriting we have the
private constructor in the base class then it is of no use as it cannot be accessed by the object in
the derived class, so practically it is not available for the object. In such conditions it will raise an
error.

2. What if I do not write the constructor?


In such case the compiler will try to supply the no parameter constructor for your class behind
the scene. Compiler will attempt this only if you do not write the constructor for the class. If you
provide any constructor (with or without parameters), then compiler will not make any such
attempt.

3. What if I have the constructor public myDerivedClass () but not the public
myBaseClass ()?
It will raise an error. If either the no parameter constructor is absent or it is in-accessible ( say it
is private ), it will raise an error. You will have to take the precaution here.

4. Can we access static members from the non-static (normal) constructors?


Yes, We can. There is no such restriction on non-static constructors. But there is one on static
constructors that it can access only static members.
Extern: The extern modifier is used to declare a method that is implemented externally. A
common use of the extern modifier is with the DllImport attribute when using Interop
services to call into unmanaged code.

*Static modifier should be used in conjunction with extern keyword.

It is an error to use the abstract and extern modifiers together to modify the same member.
Using the extern modifier means that the method is implemented outside the C# code, while
using the abstract modifier means that the method implementation is not provided in the class.

1. When a method declaration includes an extern modifier, the method is said to be an external
method.
2 External methods are implemented externally, typically using a language other than C#.
3 Because an external method declaration provides no actual implementation, the method-body
of an external method simply consists of a semicolon.

Ex:
[DllImport ("avifil32.dll")]
Private static extern void AVIFileInit();

Ex:
using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);

static int Main()


{
string myString;
Console.Write("Enter your message: ");
myString = Console.ReadLine();
return MessageBox(0, myString, "My Message Box", 0);
}
}

Void:
It specifies a return value type for a method that does not return a value. (i.e.) When used as
the return type for a method, void specifies that the method does not return a value. A method
that takes no parameters and returns no value is declared as follows:

Ex:
Void Method1 ();

Void is not allowed in a method's parameter list.

Void is also used in an unsafe context to declare a pointer to an unknown type.

Void is an alias for the .NET Framework System.Void type.

Lock:
The lock keyword marks a statement block as a critical section by obtaining the mutual-
exclusion lock for a given object, executing a statement, and then releasing the lock. This
statement takes the following form:

Ex:
Object thisLock = new Object();
lock (thisLock)
{
// Critical code section
}
lock ensures that one thread does not enter a critical section of code while another thread is in
the critical section. If another thread attempts to enter a locked code, it will wait, block, until the
object is released.

lock calls Enter at the beginning of the block and Exit at the end of the block.

In general, avoid locking on a public type, or instances beyond your code's control.

The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock"):

• lock (this) is a problem if the instance can be accessed publicly.

• lock (typeof (MyType)) is a problem if MyType is publicly accessible.

• lock ("myLock") is a problem since any other code in the process using the same string,
will share the same lock.

Best practice is to define a private object to lock on, or a private static object variable to
protect data common to all instances.

Volatile:
The volatile keyword indicates that a field might be modified by multiple concurrently
executing threads. Fields that are declared volatile are not subject to compiler
optimizations that assume access by a single thread. This ensures that the most up-to-date
value is present in the field at all times.

The following example shows how to declare a public field variable as volatile.

// csharp_volatile.cs
Class Test
{
Public volatile int i;
Test (int _i)
{
i = _i;
}
}

Whenever a volatile is requested, the system returns the current value at the time of the request. All
assignments are written to the object immediately.

Common usage of the volatile modifier is when a particular field is accessed by many threads without
using the lock statement to serialize access. So in essence the volatile modifier guarantees that a thread
will retrieve the most recent value written by another thread (even if it was modified by the previous
instruction from you call).
You are not allowed to use volatile on just any type. The following is a list of types you can
implement this modifier on:

• Any reference type.


• Any pointer type in a unsafe context
• sbyte, byte, short, ushort, int, uint, char, float, bool.
• An enum type with an enum base type of the following: byte, sbyte, short, ushort, int, uint.

The volatile keyword can only be applied to fields of a class or struct. Local variables cannot be
declared volatile.

Sealed:
The sealed modifier can be applied to classes, instance methods and properties. A sealed
class cannot be inherited. A sealed method overrides a method in a base class, but itself cannot
be overridden further in any derived class.
When applied to a method or property, the sealed modifier must always be used with override.
Use the sealed modifier in a class declaration to prevent inheritance of the class
* It is an error to use a sealed class as a base class or Abstract modifier in sealed class.
* Structs are implicitly sealed; therefore, they cannot be inherited.
Ex: Sealed method

class A{
public virtual void First() {
Console.WriteLine("A.F");
}
public virtual void Second() {}
}
class B: A{ //Override keyword used along with sealed modifier in sealed method
sealed override public void First () {
Console.WriteLine("B.F");
}
override public void Second () {
Console.WriteLine("B.G");
}
}
class C: B{
override public void Second () {
Console.WriteLine("C.G");
}
}

Abstract:
The abstract modifier can be used with classes, methods, properties, indexers, and events. Use
the abstract modifier in a class declaration to indicate that a class is intended only to be a base
class of other classes. Members marked as abstract, or included in an abstract class, must be
implemented by classes that derive from the abstract class.

In this example, the class square must provide an implementation of method Area because it derives
from Abstract class Shape:

Ex:

abstract class ShapesClass{


abstract public int Area();
}
class Square : ShapesClass{
int x, y;
// Not providing an Area method results in a compile-time error.
public override int Area(){
return x * y;
}
}

Abstract classes have the following features:

* An abstract class cannot be instantiated.


* An abstract class may or maynot contain abstract methods and accessors.
* It is not possible to modify an abstract class with the sealed modifier, which means that the
class cannot be inherited.
* A non-abstract class derived from an abstract class must include actual implementations of all
inherited abstract methods and accessors.

Abstract methods have the following features:

* An abstract method is implicitly a virtual method.


* Abstract method declarations are only permitted in abstract classes.
* Because an abstract method declaration provides no actual implementation, there is no method
body; the method declaration simply ends with a semicolon and there are no curly braces ({ })
following the signature.
* The implementation is provided by an overriding method,which is a member of a non-abstract
class.
* It is an error to use the static or virtual modifiers in an abstract method declaration.

Abstract properties behave like abstract methods, except for the differences in
declaration and invocation syntax.
* It is an error to use the abstract modifier on a static property.
* An abstract inherited property can be overridden in a derived class by including a property
declaration that uses the override modifier.
* An abstract class must provide implementation for all interface members.
* An abstract class that implements an interface might map the interface methods onto abstract
methods.
interface I{
void M();
}
abstract class C : I{
public abstract void M();
}

Example for Abstract Class


// Abstract Classes
using System;
abstract class BaseClass // Abstract class
{
protected int _x = 100;
protected int _y = 150;
public abstract void AbstractMethod(); // Abstract method
public abstract int X { get; }
public abstract int Y { get; }
}

class DerivedClass : BaseClass{


public override void AbstractMethod(){
_x++;
_y++;
}

public override int X // overriding property


{
get{
return _x + 10;
}
}

public override int Y // overriding property


{
get{
return _y + 10;
}
}

static void Main(){


DerivedClass o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
}
}
Output
x = 111, y = 161

Interface:
An interface contains only the signatures of methods, delegates or events. The implementation of
the methods is done in the class that implements the interface

Interface ISampleInterface
{
Void SampleMethod ();
}
Class ImplementationClass : ISampleInterface
{
// Explicit interface member implementation:
Void ISampleInterface.SampleMethod ()
{
// Method implementation.
}
Static void Main ()
{
// declare an interface instance.
ISampleInterface obj = new ImplementationClass();
// Call the member.
obj.SampleMethod();
}
}

* An interface can be a member of a namespace or a class and can contain signatures of the
following members: Methods ; Properties ; Indexers; Events
* An interface can inherit from one or more base interfaces.
* When a base type list contains a base class and interfaces, the base class must come first in
the list.
* A class that implements an interface can explicitly implement members of that interface. An
explicitly implemented member cannot be accessed through a class instance, but only through an
instance of the interface.

using System;
interface IPoint{
int x{ // Property signatures:
get;
set;
}
int y{
get;
set;
}
}
class Point : IPoint{
private int _x;// Fields:
private int _y;
public Point(int x, int y){ // Constructor:
_x = x;
_y = y;
}
public int x{ // Property implementation:
get{
return _x;
}
set{
_x = value;
}
}
public int y{
get{
return _y;
}
set{
_y = value;
}
}
}
class MainClass{
static void PrintPoint(IPoint p){
Console.WriteLine("x={0}, y={1}", p.x, p.y);
}
static void Main(){
Point p = new Point(2, 3);
Console.Write("My Point: ");
PrintPoint(p);
}
}
Output
My Point: x=2, y=3

Difference between Interfaces and Abstract Classes

Interface Abstract Class

1. Multiple inheritance is possible Multiple inheritance is not allowed

2. Members cannot have implementation May have non abstract members


only declaration is allowed with implementation
3. Fields or variables are not allowed Variables are allowed in Abstract
in Interface classes
4. Access Modifiers are not allowed Access Modifiers are allowed in
in Interfaces abstract class

5. All the members of Interface should be Only the members marked as Abstract need
implemented in the derived class to be implemented in the derived class
6. If we add new method to an interface If new methods are added they can be
we need to track down all the inherited implemented in the class itself so no need to
classes and implement these methods implement in inherited classes

Params:
The params keyword lets you specify a method parameter that takes an argument where the
number of arguments is variable.

No additional parameters are permitted after the params keyword in a method declaration, and
only one params keyword is permitted in a method declaration.

Ex:
using System;
public class MyClass{
public static void UseParams(int y,params int[] x) {
for (int i = 0; i < x.Length; i++){
Console.Write (x[i]);
}
Console.Write (y);
}
static void Main(){
UseParams(5,1, 2, 3);
}
}
Output:
1235
Ref & Out Parameters:

Ref:
The ref keyword causes arguments to be passed by reference. The effect is that any
changes made to the parameter in the method will be reflected in that variable when control
passes back to the calling method. To use a ref parameter, both the method definition and the
calling method must explicitly use the ref keyword

*An argument passed to a ref parameter must first be initialized.


*This differs from out, whose argument need not be explicitly initialized before being passed
* Properties are not variables and therefore cannot be passed as ref parameters.

static void Main()


{
int refx=0 ; //variable passed as reference ,Should be initialised before
using ,else cause Compilation error
int x = 1;// variable going to be passed as value
Console.Write("From the main: ");
Console.Write(refx);
Console.Write(" , ");
Console.WriteLine(x);
Method(ref refx, x); // sending refx as ref and x as value
Console.Write("From the main: ");
Console.Write(refx);
Console.Write(" , ");
Console.Write(x);
Console.ReadKey();
}
static void Method(ref int i,int j)
{
i = 10; j = 2;//Value for both variables is changed in the called function
Console.Write("From the method: ");
Console.Write(i);
Console.Write(" , ");
Console.WriteLine(j);
}
Output:
From the main: 0, 1 //values before modification in method
From the method: 10, 2 // values in the method
From the main: 10, 1 // values after modification in method (value passed as ref gets changed)

Although ref and out are treated differently at run-time, they are treated the same at compile
time. Therefore methods cannot be overloaded if one method takes a ref argument and the other
takes an out argument. These two methods, for example, are identical in terms of compilation,
so this code will not compile
Class Example
{
// compiler error CS0663: "cannot define overloaded
// methods that differ only on ref and out"
Public void Method (ref int I) { }
Public void Method (out int I) { }
}
Overloading can be done, however, if one method takes a ref or out argument and the other
uses neither, like this:

Class RefOutOverloadExample
{
Public void Method (int I) { }
Public void Method (ref int I) { }
}

Ref is also useful for passing reference types. This allows called methods to modify the object to
which the reference refers because the reference itself is being passed by reference. The
following sample shows that when a reference type is passed as a ref parameter, the object itself
can be changed.

Out:
The out keyword causes arguments to be passed by reference. This is similar to the ref
keyword, except that ref requires that the variable be initialized before being passed. To use an
out parameter, both the method definition and the calling method must explicitly use the out
keyword.

Class Example
{
Static void Method (out int I)
{
I = 44; // need to be initialized before method returns
}
Static void Main ()
{
int value;
Method (out value);
// value is now 44
}
}
* Although variables passed as an out arguments need not be initialized prior to being passed,
the called method is required to assign a value before the method returns.

Passing Arrays Using ref and out:


In this example, the array myArray is declared in the caller (the Main method), and initialized in
the FillArray method. Then, the array elements are returned to the caller and displayed.

class TestOut
{
static void FillArray(out int[] arr) {
// Initialize the array:
arr = new int[5] { 1, 2, 3, 4, 5 };
}

static void Main()


{
int[] theArray; // Initialization is not required
FillArray(out theArray); // Pass the array to the callee using out:

// Display the array elements:


System.Console.Write ("Array elements are:");
for (int i = 0; i < theArray.Length; i++)
{
System.Console.Write(theArray[i] + " ");
}
}
}

Output 1
Array elements are: 1 2 3 4 5
In this example, the array theArray is initialized in the caller(the Main method), and passed to
the FillArray method by using the ref parameter. Some of the array elements are updated in the
FillArray method. Then, the array elements are returned to the caller and displayed.

class test
{
static void FillArray(ref int[] arr)
{
// Create the array on demand:
if (arr == null)
{
arr = new int[10];
}
// Fill the array:
arr[0] = 1111;
arr[4] = 5555;
}
static void Main()
{
// Initialize the array:
int[] theArray = { 1, 2, 3, 4, 5 };

// Pass the array using ref:


FillArray(ref theArray);

// Display the updated array:


System.Console.WriteLine("Array elements are:");
for (int i = 0; i < theArray.Length; i++)
{
System.Console.Write(theArray[i] + " ");
}
}
}

Output:
Array elements are: 1111 2 3 4 5555

Unsafe:
The unsafe keyword denotes an unsafe context, which is required for any operation involving
pointers.

The unsafe content will not run under CLR. We have to use Compile with Unsafe option
to run these codes. (Properties_Build –Allow Unsafe Code should be checked)

You can use the unsafe modifier in the declaration of a type or a member. The entire textual
extent of the type or member is therefore considered an unsafe context. For example, the
following is a method declared with the unsafe modifier:

Unsafe static void Copy (byte [] source, byte [] destination, int count)
{
// Unsafe context: can use pointers here.
}

The scope of the unsafe context extends from the parameter list to the end of the method, so
pointers can also be used in the parameter list:

Unsafe static void Copy (byte* ps, byte* Pd, int count)
{...}

We can also use an unsafe block to enable the use of an unsafe code inside this block.
Unsafe
{
// Unsafe context: can use pointers here.
}

Unsafe code has the following properties:

* Methods, types, and code blocks can be defined as unsafe.

* Unsafe code may increase an application's performance by removing array bounds checks.

* Unsafe code is required when calling native functions that require pointers.

* Using unsafe code introduces security and stability risks.

* In order for C# to compile unsafe code, the application must be compiled with /unsafe.

Ex:
class UnsafeTest
{
// Unsafe method: takes pointer to int:
unsafe static void SquarePtrParam(int* p)
{
*p = *p * *p; // *p *= *p;
}
unsafe static void Copy(byte* ps, byte* Pd, int count)
{}

unsafe static void Main()


{
int i = 5;
// Unsafe method: uses address-of operator (&):
SquarePtrParam(&i);
Console.WriteLine(i);
Console.ReadKey();
}
}
Output : 25

New:
In C#, the new keyword can be used as an operator, a modifier, or a constraint.

New Operator: Used to create objects and invoke constructors.

Class1 o = new Class1(); //Creating object


The new operator is also used to invoke the default constructor for value types. For example:

int x = new int(); // Invokes Constructor

In the preceding statement, x is initialized to ‘0’, which is the default value for the type int. The
statement has the same effect as the following:
int x=0;

New Modifier: Used to hide an inherited member from a base class member.
When used as a modifier, the new keyword explicitly hides a member inherited from a
base class. Hiding an inherited member means that the derived version of the member replaces
the base-class version. Hiding members without the use of the new modifier is allowed, but
generates a warning. Using new to explicitly hide a member suppresses this warning, and
documents the fact that the derived version is intended as a replacement.

To hide an inherited member, declare it in the derived class using the same name, and modify it
with the new modifier

public class BaseC


{
public int x;
public void Invoke() { }
}
public class DerivedC : BaseC
{
new public void Invoke() { }
}

It is an error to use both new and override on the same member, as the two modifiers have
mutually exclusive meanings.

Using new creates a new member with the same name and causes the original member to
become hidden, while override extends the implementation for an inherited member.

Using the new modifier in a declaration that does not hide an inherited member generates a
warning.

public class BaseC


{
public static int x = 55;
public static int y = 22;
}

public class DerivedC : BaseC


{
// Hide field 'x'
new public static int x = 100;

static void Main()


{
// Display the new value of x:
Console.Write (x);
// Display the hidden value of x:
Console.Write (BaseC.x);
// Display the unhidden member y:
Console.Write (y);
}
}

Output : 100 55 22
In the above example, a base class, BaseC, and a derived class, DerivedC, use the same field
name x, thus hiding the value of the inherited field.. It also demonstrates how to access the
hidden members of the base class by using their fully qualified names

New Constraint: Used to restrict types that might be used as arguments for a type parameter in a
generic declaration.

The new constraint specifies that any type argument in a generic class declaration must have a
public parameter less constructor. Apply this constraint to a type parameter when your generic
class creates new instances of the type, as shown in the following example:

class ItemFactory<T> where T : new()


{
public T GetNewItem()
{
return new T();
}
}

When you use the new () constraint with other constraints, it must be specified last:
class ItemFactory<T> where T : IComparable, new() {}

Base:
The base keyword is used to access members of the base class from within a derived class.

* Call a method on the base class that has been overridden by another method.

* Specify which base-class constructor should be called when creating instances of the derived class.
* A base class access is permitted only in a constructor, an instance method, or an instance property
accessor.
* It is an error to use the base keyword from within a static method.
In this example, both the base class Person, and the derived class Employee, have a method
named GetInfo. By using the base keyword, it is possible to call the GetInfo method on the base
class, from within the derived class.

Ex:

// Accessing base class members


using System;
public class Person
{
protected string ssn = "444-55-6666";
protected string name = "John L. Malgraine";

public virtual void GetInfo(){


Console.WriteLine("Name: {0}", name);
Console.WriteLine("SSN: {0}", ssn);
}
}
class Employee : Person
{
public string id = "ABC567EFG";
public override void GetInfo(){
base.GetInfo(); // Calling the base class GetInfo method:
Console.WriteLine("Employee ID: {0}", id);
}
}

class TestClass
{
static void Main(){
Employee E = new Employee();
E.GetInfo();
}
}

Output:
Name:John L. Malgraine
SSN : 444-55-6666
Employee ID: ABC567EFG

This example shows how to specify the base-class constructor called when creating instances of a
derived class.

using System;
public class BaseClass
{
int num;
public BaseClass(){
Console.WriteLine("in BaseClass()");
}
public BaseClass(int i){
num = i;
Console.WriteLine("in BaseClass(int i)");
}
public int GetNum() {
return num;
}
}
public class DerivedClass : BaseClass
{
// This constructor will call BaseClass.BaseClass()
public DerivedClass(): base()
{
}
// This constructor will call BaseClass.BaseClass(int i)
public DerivedClass(int i): base(i)
{
}
static void Main() {
DerivedClass md = new DerivedClass();
DerivedClass md1 = new DerivedClass(1);
}
}

Output:
in BaseClass()
in BaseClass(int i)

This:
The this keyword refers to the current instance of the class.

The following are common uses of this:

To qualify members hidden by similar names, for example:

Public Employee (string name, string alias) {

this.name = name;

this.alias = alias;

To pass an object as a parameter to other methods, for example:

CalcTax (this);

To declare indexers, for example:

Public int this [int param]

get {return array [param];}


set {array [param] = value; }

* Static member functions do not have this pointer because they exist at the class level and not
as part of an object. It is an error to refer to this in a static method

In this example, this is used to qualify the Employee class members, name and alias, which are
hidden by similar names. It is also used to pass an object to the method CalcTax, which belongs
to another class

Ex:

using System;
class Employee

{
private string name;
private string alias;
private decimal salary = 3000.00m;
public Employee()
{
this.name = "xxx"; // Use this to qualify the fields, name and alias:
this.alias = "yyy";
}
// Constructor:
public Employee(string name, string alias) {
this.name = name; // Use this to qualify the fields, name and alias:
this.alias = alias;
}
public void printEmployee() { // Printing method:
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
// Passing the object to the CalcTax method by using this:
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this));
}
public decimal Salary {
get { return salary; }
}
}
class Tax
{
public static decimal CalcTax(Employee E) {
return 0.08m * E.Salary;
}
}

class MainClass
{
static void Main() {
// Create objects:
Employee E0 = new Employee();
E0.printEmployee();
Employee E1 = new Employee("John M. Trainer", "jtrainer");
// Display results:
E1.printEmployee();
Console.ReadKey();
}
}
Output:
Name: xxx
Alias: yyy
Taxes: $240.00
Name: John M. Trainer
Alias: jtrainer
Taxes: $240.00

Properties:
Properties are members that provide a flexible mechanism to read, write, or compute
the values of private fields. Properties can be used as though they are public data members, but
they are actually special methods called accessors. This enables data to be accessed easily while
still providing the safety and flexibility of methods.

The code block for the get accessor is executed when the property is read; the code block for the
set accessor is executed when the property is assigned a new value. A property without a set
accessor is considered read-only. A property without a get accessor is considered write-only. A
property with both accessors is read-write.

Ex:

public class Car


{
private string color;// private fields.
public Car() // constructor
{
}
public string PropColor
{
get
{
return color; // return the value from privte field.
}
set
{
color = value; // save value into private field.
}
}
}

The above class has one private field - color. Then we have one "Property" called “PropColor”,
which is used to represent the private field. Note that the field is private and the Property is
public.

Each property has two parts:


get
 set
the get part is executed when you access the value of the Property as shown below:

Car car = new Car();


string color = car.PropColor;

When executed, the above get accessor will return the value stored in the field 'color'.

The set part is executed when you assign a value to the Property as shown below:

Car car = new Car();


car.PropColor = "RED";

When executed, the above set accessor will assign the value "RED" to the private field 'color'. (Note
that 'value' is a keyword, which will have the value assigned to it.)

So, what is the difference ?


On the first look, there is no difference! You can achieve the same behavior by writing 2 different
methods ( like SetColor(...), GetColor() ).
First advantage of using property is, code looks cleaner than having 2 separate methods. You can
simply call a property as if it was a field in the class.
Well, then you may ask why make it 2 methods, we can make it a public field, so that we can access it
by creating an instance of the class.
The main advantage over using a Property instead of a public field is, with the property, you will get a
chance to write few lines of code (if you want) in the get and set accessors. So, you can perform some
validation or any other logic before returning any values or assigning to the private field.

public class Car


{
private string color; // private fields.
public Car()// constructor
{
}
public string PropColor
{
get
{
if (color == "")
return "GREEN";
else
return color;
}
set
{
if ( value == "" )
throw new Exception ("Wrong value.");
else
color = value;
}
}
}

Let us analyze the get part first. Here we are checking whether there is a valid value in the field 'color'
before we return the value. If it is empty, we are getting a chance to return a default value 'Green'. This
way, we can make sure that whoever calls the property ‘Color’ will always gets a valid color, never an
empty string.
In the set part, we are doing a validation to make sure we always assign a valid value to our field. If
someone assigns an empty string to the 'Color' property, he will get an exception (error).

Indexer:
Indexers permit instances of a class or struct to be indexed in the same way as arrays.
Indexers are similar to properties except that their accessors take parameters.

Declaration:

<access modifier> <return type> this [argument list]


{
get{
// Get codes goes here
}
set{
// Set codes goes here
}
}

* The modifier can be private, public, protected or internal.


* The return type can be any valid C# types.
* The 'this' is a special keyword in C# to indicate the object of the current class.
* The formal-argument-list specifies the parameters of the indexer and at least one parameter
must be specified.
* the ref and out parameter modifiers are not permitted
* Static keyword is not allowed in Indexer declaration
* With Indexer we can implement Inheritance, Polymorphism (Overloading, Overriding) and
Abstraction concepts.
Ex:

using System;
using System.Collections;

class MyClass
{
private string[] data = new string[5];
public string this[int index]{
get {
return data[index];
}
set {
data[index] = value;
}
}
}
class MyClient
{
public static void Main() {
MyClass mc = new MyClass();
mc[0] = "Rajesh";
mc[1] = "Ponmalai";
mc[2] = "Trichy";
mc[3] = "TamilNadu";
mc[4] = "India";
Console.WriteLine("{0},{1},{2},{3},{4}", mc[0], mc[1], mc[2], mc[3], mc[4]);
Console.ReadKey();
}
}
Output: Rajesh, Ponmalai, Trichy, TamilNadu, India.

Indexers & Properties

1. An indexer is identified by its signature. But a property is identified its name.


2. An indexer is always an instance member, but a property can be static also.
3. An indexer is accessed through an element access. But a property is through a member
access.

Differences between Property and Indexer


Property Indexer
Allows methods to be called as though they Allows methods on an object to be called as though
were public data members. the object is an array.
Accessed through a simple name. Accessed through an index.
Can be a static or an instance member. Must be an instance member.
A get accessor of an indexer has the same formal
A get accessor of a property has no parameters.
parameter list as the indexer.
A set accessor of an indexer has the same formal
A set accessor of a property contains the implicit
parameter list as the indexer, in addition to the value
value parameter.
parameter.

StringBuilder:
The class StringBuilder, in namespace System.Text which provides us with a dynamic string
builder class. Normally if we have used the string data type it will create a new string object each
time we modify the string, and refer to that new object. This can harm the performance of the
application, but the class StringBuilder supports string modifications without creating a new
object.

Partial Class:
It is possible to split the definition of a class or a struct, or an interface (not available in
Delegate or Enumeration) over two or more source files. Each source file contains a section of the
class definition, and all parts are combined when the application is compiled. There are several
situations when splitting a class definition is desirable:

When working on large projects, spreading a class over separate files allows multiple
programmers to work on it simultaneously.

When working with automatically generated source, code can be added to the class without having to
recreate the source file. Visual Studio uses this approach when creating Windows Forms, Web
Service wrapper code, and so on. You can create code that uses these classes without having to edit
the file created by Visual Studio.
Using the partial keyword indicates that other parts of the class, struct, or interface can be defined
within the namespace. All the parts must use the partial keyword. All of the parts must be available
at compile time to form the final type. All the parts must have the same accessibility, such as public,
private, and so on.
If any of the parts are declared abstract, then the entire type is considered abstract. If any of the
parts are declared sealed, then the entire type is considered sealed. If any of the parts declare a
base type, then the entire type inherits that class.

All partial-type definitions meant to be parts of the same type must be defined in the same
assembly and the same module (.exe or .dll file). Partial definitions cannot span multiple modules

class Container {
partial class Nested {
Void Test () { }
}
partial class Nested {
Void Test2 () { }
}
}

At compile time, attributes of partial-type definitions are merged. the following declarations:
[System.SerializableAttribute]
partial class Moon { }
[System.ObsoleteAttribute]
partial class Moon { } // are equivalent to:

[System.SerializableAttribute]
[System.ObsoleteAttribute]
class Moon { }

Example:
public partial class CoOrds {
private int x; private int y;
public CoOrds(int x, int y){
this.x = x;
this.y = y;
}
}
public partial class CoOrds {
public void PrintCoOrds(){
System.Console.WriteLine("CoOrds: {0},{1}", x, y);
}
}
class TestCoOrds {
static void Main(){
CoOrds myCoOrds = new CoOrds(10, 15);
myCoOrds.PrintCoOrds();
}
} Output : CoOrds: 10, 15

Break:
The break statement terminates the closest enclosing loop or switch statement in which it
appears. Control is passed to the statement that follows the terminated statement, if any.

In this example, the conditional statement contains a counter that is supposed to count from 1 to
100; however, the break statement terminates the loop after 4 counts.

class BreakTest {
static void Main() {
for (int i = 1; i <= 100; i++){
if (i == 5) {
break;
}
Console.Write(i);
}
}
}

Output: 1 2 3 4

Switch:
The switch statement is a control statement that handles multiple selections and enumerations
by passing control to one of the case statements within its body.

* Control is transferred to the case statement which matches the value of the switch.

* The switch statement can include any number of case statements.

* But no two case statements can have the same value.

* Execution of the statement body begins at the selected statement and proceeds until the break
statement transfers control out of the case body.

* A jump statement such as a break is required after each case block, including the last block
whether it is a case statement or a default statement.

* With one exception, C# does not support an implicit fall through from one case label to
another. The one exception is if a case statement has no code.

* If no case expression matches the switch value, then control is transferred to the statement(s)
that follow the optional default label. If there is no default label, control is transferred outside
the switch.

* Default block can be given anywhere

// n should be defined earlier as int and according to value in n it will be searched in case
switch (n) // n = 1 or 2 or 3
{
case 1:
case 2:
case 3:
Console.WriteLine("It's 1, 2, or 3.");
break;
default:
Console.WriteLine("Not sure what it is.");
break;
}
Output : It's 1, 2, or 3.

switch (n) // n = 1 or 2 or any other number


{
case 1:
case 2:
default:
Console.WriteLine("Not sure what it is.");
break;
case 3:
Console.WriteLine("It's 1, 2, or 3.");
break;

}
Output : Not sure what it is.

Enum:
Enum is a complex type of variable which can take one of a fixed set of results.

Defining Enumerations
Enumerations can be defined using the enum keyword as follows:
enum typeName: Underlying type
{
value1,
value2,
value3,
...
valueN
}
Next, you can declare variables of this new type with
typeName varName;
and assign values using:
VarName = typeName.value;

Example
namespace ConsoleApplication1 {
enum orientation :int { //int is the underlying type which can be assigned
// byte, sbyte, short, ushort, int, uint, long, or ulong are allowed
north=20 ,
south=30,
east=4 ,
west
} //float or string are not allowed to store in enum
class Program {
static void Main(string[] args) {
orientation myDirection = orientation.north;
Console.WriteLine("myDirection = {0}",myDirection);
orientation myDirection1 = orientation.north;
Console.WriteLine("myDirection = {0}", (byte)myDirection1);
orientation myDirection2 = orientation.east;
Console.WriteLine("myDirection = {0}", (byte)myDirection2);
orientation myDirection3 = orientation.west;
Console.WriteLine("myDirection = {0}", (byte)myDirection3);
Console.ReadKey();
}
}
} Output:
myDirection = north ; myDirection = 20 ;myDirection = 4
myDirection = 5

Struct:
A struct type is a value type that is typically used to encapsulate small groups of related variables.
Structs are defined using the struct keyword, for example:

Public struct PostalAddress


{
// Fields, properties, methods and events go here...
}

* Structs share almost all the same syntax as classes but it is more limited than classes.

* In struct declaration, fields cannot be initialized unless they are declared as const or static.

* A struct cannot declare a constructor with no parameters — or a destructor.

* Structs cannot inherit from classes or other structs.

* Structs can also contain constructors, constants, fields, methods, properties, indexers,
operators, events, and nested types, although if several such members are required, it is better
to make it as a class instead.

* A class variable can be assigned null. But we cannot assign null to a struct variable, since
structs are value type.

* When a class is instantiated, it will be allocated on the heap. When you instantiate a struct, it
gets created on the stack.
* Structs can implement an interface but they cannot inherit from another struct. For that
reason, struct members cannot be declared as protected.

Structs are value types — when an object is created for a struct and assigned to a variable, the
variable contains the entire value of the struct. When a variable containing a struct is copied, all
of the data is copied, and any modification to the new copy does not change the data for the old
copy.

Structs Overview

* Structs are value types while classes are reference types.

* Unlike classes, structs can be instantiated without using a new operator. If you do not use
new, the fields will remain unassigned and the object cannot be used until all of the fields are
initialized

* Structs can declare constructors, but they must take parameters.

* A struct cannot inherit from another struct or class, and it cannot be the base of a class. All
structs inherit directly from System.ValueType, which inherits from System.Object.

* A struct can implement interfaces.

Ex:

namespace ConsoleApplication1 {
enum orientation : byte {
north = 1,
south = 2,
east = 3,
west = 4
}
struct route {
public orientation direction;
public double distance;
}

class Program {
static void Main(string[] args) {
route myRoute;
int myDirection = -1;
double myDistance;
Console.WriteLine("1) North\n2) South\n3) East\n4) West");
do {
Console.WriteLine("Select a direction:");
myDirection = Convert.ToInt32(Console.ReadLine());
}
while ((myDirection < 1) || (myDirection > 4));
Console.WriteLine("Input a distance:");
myDistance = Convert.ToDouble(Console.ReadLine());
myRoute.direction = (orientation)myDirection;
myRoute.distance = myDistance;
Console.WriteLine("myRoute specifies a direction of {0} and a " +
"distance of {1}", myRoute.direction, myRoute.distance);
Console.ReadKey();
}
}
}

Ex:

public struct CoOrds


{
public int x, y;
public CoOrds(int p1, int p2) {
x = p1;
y = p2;
}
}

class TestCoOrds
{
static void Main() {
// Initialize:
CoOrds coords1 = new CoOrds();
CoOrds coords2 = new CoOrds(10, 10);

// Display results:
System.Console.Write("CoOrds 1: ");
System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);

System.Console.Write("CoOrds 2: ");
System.Console.WriteLine("x = {0}, y = {1}", coords2.x, coords2.y);
}
}
Output: coOrds 1: x = 0, y = 0 ; coOrds 2: x = 10, y = 10

// Declare a struct object without "new."


class TestCoOrdsNoNew
{
static void Main()
{
// Declare an object:
CoOrds coords1;

// Initialize:
coords1.x = 10;
coords1.y = 20;

// Display results:
System.Console.Write("CoOrds 1: ");
System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
}
}
Output: coords 1: x = 10, y = 20
This following shows that when a struct is passed to a method, a copy of the struct is passed, but
when a class instance is passed, a reference is passed.

The output of the following example shows that only the value of the class field is changed when
the class instance is passed to the ClassTaker method. The struct field, however, does not change
by passing its instance to the StructTaker method. This is because a copy of the struct is passed
to the StructTaker method, while a reference to the class is passed to the ClassTaker method.

using System;
class TheClass {
public string willIChange;
}
struct TheStruct {
public string willIChange;
}

class TestClassAndStruct {
static void ClassTaker(TheClass c) {
c.willIChange = "Changed";
}
static void StructTaker(TheStruct s) {
s.willIChange = "Changed";
}
static void Main() {
TheClass testClass = new TheClass();
TheStruct testStruct = new TheStruct();

testClass.willIChange = "Not Changed";


testStruct.willIChange = "Not Changed";

ClassTaker(testClass);
StructTaker(testStruct);

System.Console.WriteLine("Class field = {0}", testClass.willIChange);


System.Console.WriteLine("Struct field = {0}", testStruct.willIChange);
}
}

Output: Class field = Changed; Struct field = Not Changed

Array:
Arrays are indexed lists of variables stored in a single array type variable. Arrays have a
single base type, that is, individual entries in an array are all of the same type.

Declaring Arrays
Arrays are declared in the following way:
<baseType>[] <name>;
Ex:
int[] myIntArray = new int[5]; //or
int[] myIntArray = { 5, 9, 10, 2, 99 };
string[] strarray ={ "Hi", "How", "Are", "You" };
int[] myIntArray = new int[5] { 5, 9, 10, 2, 99 };
int[] myIntArray = new int[10] { 5, 9, 10};//Error size and content does not match
int[] myIntArray = new int[arraySize];//arraysize is a variable but that variable
should be constant (constant int arraySize =5;)
Ex:
string[] friendNames = {"Robert Barwell", "Mike Parry","Jeremy Beacock"};
int i;
Console.WriteLine("Here are {0} of my friends:", friendNames.Length);
for (i = 0; i < friendNames.Length; i++) {
Console.WriteLine(friendNames[i]); // accessing array content
}
Console.ReadKey();

Foreach:
A foreach loop allows you to address each element in an array using this simple syntax: Foreach
loop is read only.

foreach (<baseType> <variablename> in <array>)


{
// can use <variablename> for each element
}
Ex:
static void Main(string[] args)
{
string[] friendNames = {"Robert Barwell", "Mike Parry", "Jeremy Beacock"};
Console.WriteLine("Here are {0} of my friends:",friendNames.Length);
foreach (string friendName in friendNames)
{
Console.WriteLine(friendName);
}
Console.ReadKey();
}

String Manipulation:
string myString = "A string";
char myChar = myString[1]; //String can be considered as Char array
string myString = "A string"; //To assign a value should be coverted to char array
char[] myChars = myString.ToCharArray();
int a = myString.Length; // a = 8
string b = myString.ToLower(); // b = a string
string c = myString.ToUpper(); // c = A STRING
string d = myString.Trim(); // if “ A String “ then d = “A String”
string e = myString.TrimStart(); // if “ A String “ then d = “A String ”
string f = myString.TrimEnd(); // if “ A String “ then d = “ A String”
string g= myString.Substring(4); // b = ring ,starts with 0 index
string h = myString.Substring(3,2);// b = tr

char[] trimChars = { 'A', 'e', 'g' };


string i = myString.Trim(trimChars); //i=” strin” will work on end characters only

string j = myString.PadLeft(10); //10= length + 2, 2 spaces will be added to left


string k = myString.PadRight(12);//12= length + 4, 4 spaces will be added to right

string myString = "This is a test";


string i=mystring.Replace(" ",""); // i= Thisisatest replaces space with null

string myString = "This s a test";


char[] separator = {' ',’i’};
string[] myWords;
myWords = myString.Split(separator); // string will be split at spaces and ‘i’
foreach (string word in myWords) {
Console.WriteLine("{0}", word);
} output:Th;s;s;a;test

Boxing and Unboxing:


Boxing and unboxing enable value types to be treated as objects. Boxing a value type packages it
inside an instance of the Object reference type. This allows the value type to be stored on the
garbage collected heap. Unboxing extracts the value type from the object. In this example, the
integer variable i is boxed and assigned to object o.

int i = 123;
object o = (object)i; // boxing

The object o can then be unboxed and assigned to integer variable i:

o = 123;

i = (int)o; // unboxing

Performance:

In relation to simple assignments, boxing and unboxing are computationally expensive processes.
When a value type is boxed, an entirely new object must be allocated and constructed. To a
lesser degree, the cast required for unboxing is also expensive computationally as it needs to
check if the boxed variable is not null or the types are equal.
Command-Line Arguments:
Arguments provided to an executable on the command-line are called Command-Line
Arguments. These are accessible through an optional parameter to Main. The arguments are
provided in the form of an array of strings. Each element of the array contains one argument.
White-space between arguments is removed.
The Main method can use arguments, in which case, it takes one of the following forms:

static int Main(string[] args) // returns Int

static void Main(string[] args) // returns void

Ex:
namespace ConsoleApplication6 {
class CommandLine {
static void Main(string[] args) {
// The Length property provides the number of array elements
System.Console.WriteLine("parameter count = {0}", args.Length);

for (int i = 0; i < args.Length; i++) {


System.Console.Write ("Arg[{0}] = [{1}]", i, args[i]);
}
}
}
}
The above program can be executed as
..../../ConsoleApplication6.exe arg1 arg2 45 24 58
Output:

parameter count =5

Arg[0] = arg1; Arg[1] = arg2 ; Arg[2] = 45; Arg[3] = 24; Arg[4] = 58

Shallow Copy & Deep Copy:


Shallow Copy (memberwise copy): It creates a new instance of the same type as the original
object, and then copies the nonstatic fields of the original object. If the field is a value type, a bit-
by-bit copy of the field is performed. If the field is a reference type, the reference is copied but
the referred object is not; therefore, the reference in the original object and the reference in the
clone point to the same object.
For example, if X is an Object with references to the objects A and B, and the object A also
has a reference to an object M, a shallow copy of X is an object Y, which also has references to
objects A and B.
Deep Copy: Refers to a method of cloning, Deep copy of an object duplicates everything directly
or indirectly referenced by the fields in the object. Interface ICloneable is needed to achieve deep
copying.
A deep copy of X is an object Y with direct references to objects C and D, and an indirect
reference to object N, where C is a copy of A, D is a copy of B, and N is a copy of M.
Hence a change in cloned element does not affect the original elements.

The Type of the clone is the same as the type of the original Object.

Collection Classes:
The .NET Framework provides specialized classes for data storage and retrieval. These
classes provide support for stacks, queues, lists, and hash tables. Most collection classes
implement the same interfaces, and these interfaces may be inherited to create new collection
classes that fit more specialized data storage needs.

Collection Classes Overview

* Collection classes are defined as part of the System.Collections or System.Collections.Generic


namespace.

* Most collection classes derive from the interfaces ICollection, IComparer, IEnumerable,
IList, IDictionary, and IDictionaryEnumerator and their generic equivalents.

* Using generic collection classes provides increased type-safety and in some cases can provide
better performance, especially when storing value types

There are a number of interfaces in the System.Collections namespace that provide basic
collection functionality:

• IEnumerable: Provides the capability to loop through items in a collection.


• ICollection: Provides the ability to obtain the number of items in a collection and to copy
items into a simple array type (inherits from IEnumerable).
• IList: Provides a list of items for a collection along with the capabilities for accessing
these items, and some other basic capabilities related to lists of items (inherits from
IEnumerable and ICollection).
• IDictionary: Similar to IList, but provides a list of items accessible via a key value rather
than an index (inherits from IEnumerable and ICollection).

The System.Array class implements IList, ICollection, and IEnumerable, but doesn't support some
of the more advanced features of IList, and represents a list of items with a fixed size.
Class Description

Implements the IList interface using an array whose size is


ArrayList
dynamically increased as required.

Manages a compact array of bit values, which are


BitArray represented as Booleans, where true indicates that the bit
is on (1) and false indicates the bit is off (0).

Compares two objects for equivalence, ignoring the case of


CaseInsensitiveComparer
strings.

Supplies a hash code for an object, using a hashing


CaseInsensitiveHashCodeProvider
algorithm that ignores the case of strings.

Provides the abstract base class for a strongly typed


CollectionBase
collection.

Compares two objects for equivalence, where string


Comparer
comparisons are case-sensitive.

Provides the abstract base class for a strongly typed


DictionaryBase
collection of key/value pairs.

Represents a collection of key/value pairs that are


Hashtable
organized based on the hash code of the key.

Queue Represents a first-in, first-out collection of objects.

Provides the abstract base class for a strongly typed non-


ReadOnlyCollectionBase
generic read-only collection.

Represents a collection of key/value pairs that are sorted


SortedList
by the keys and are accessible by key and by index.

Represents a simple last-in-first-out (LIFO) non-generic


Stack
collection of objects.
Interfaces

Interface Description

Defines size, enumerators, and synchronization methods for all


ICollection
nongeneric collections.

IComparer Exposes a method that compares two objects.

IDictionary Represents a nongeneric collection of key/value pairs.

IDictionaryEnumerator Enumerates the elements of a nongeneric dictionary.

Exposes the enumerator, which supports a simple iteration over a non-


IEnumerable
generic collection.

IEnumerator Supports a simple iteration over a nongeneric collection.


IEqualityComparer Defines methods to support the comparison of objects for equality.

IHashCodeProvider Supplies a hash code for an object, using a custom hash function.

Represents a non-generic collection of objects that can be individually


IList
accessed by index.
Structures

Structure Description

DictionaryEntry Defines a dictionary key/value pair that can be set or retrieved.

Queue: ( System.Collections )

Public class Queue: ICollection, IEnumerable, ICloneable

Queue is a Simple DataStucture which allows Insert/Remove of Items at one of the ends only. It is
basically called as FIFO (First In First Out) data structure. i.e. the item which is added first is the first
one to be removed. .NET has a built in class for Queue. It is found in System.Collections namespace.
Any type of objects can be stored in Queue and the Queue capacity increases as per its growth
factor (default 2) if the limit is reached and further elements are added.

Initialization of Queue: (Have 4 overloaded methods)

Queue q0 = new Queue(); // Initializes an empty queue


Queue q1 = new Queue(ICollection q0);// Copies the collection object q0 to q1
Queue q2 = new Queue(5); //Initializes queue with initial capacity of 5
Queue q3 = new Queue(5,2);//Initializes with capacity of 5 and growth factor of 2

Adding Items to the Queue:


To add items to the Queue you use Enqueue method. This method takes an object of any type
q.Enqueue("hi");
q.Enqueue("how");
q.Enqueue("old");
q.Enqueue("are");
q.Enqueue("you");
q.Enqueue(24.5);

Peek() Method : Used to view the Top most object without removing it from Queue
object o=q.Peek(); // o = hi
GetEnumerator() Method : Used to view all the objects without removing it from Queue

Enumerators can be used to read the data in the collection, but they cannot be used to
modify the underlying collection. Initially, the enumerator is positioned before the first element in
the collection. At this position, Current is undefined. Therefore, you must call MoveNext to
advance the enumerator to the first element of the collection before reading the value of Current

IEnumerator IE = q.GetEnumerator(); //IE gets all the value of q (full capacity)


while (IE.MoveNext()) // Moves from one element to another
{
Console.Write("{0} ", IE.Current); //IE.current has the present object
}

Output: hi how old are you 24.5

An enumerator remains valid as long as the collection remains unchanged. If changes are made
to the collection, such as adding, modifying, or deleting elements, the enumerator is
irrecoverably invalidated and its behavior is undefined. The enumerator does not have exclusive
access to the collection; therefore, enumerating through a collection is intrinsically not a thread-
safe procedure. To guarantee thread safety during enumeration, you can lock the collection
during the entire enumeration. To allow the collection to be accessed by multiple threads for
reading and writing, you must implement your own synchronization.

Removing Items from the Queue:


To pop or remove an item from the Queue you can use the Dequeue statement. This returns the
topmost object of the queue.
object removed=q.Dequeue(); // removed = hi

object[] qarray = new object[10];

int count = q.Count; //returns the number of elements in queue (presently 5)


q.TrimToSize(); //Sets the capacity to actual number of elements in queue
qarray = q.ToArray(); //Copies all the elements of q to qarray (Len becomes q len)
bool y = q.IsSynchronized;// returns whether the queue is synchronized
q.CopyTo(qarray, 2); //Copies all the elements of q to qarray (Len remains)
object o1 = q.Clone(); //creates a shallow copy of the queue
bool x = q.Contains(" "); //checks and returns whether specified object is present
q.Clear(); //deletes all the elements in queue , it becomes empty

Stack:
Stack is a Simple DataStucture which allows Insert/Remove of Items at one end (same
end). It is basically called as LIFO (Last In First Out) data structure (i.e. the item which is added
last is the first one to be removed)

Common functions

• Push (): Adds a new object to the last position of the stack.
• Pop (): Returns and removes the last object of the stack.
• Peek (): Returns the last object without removing it.
• IsEmpty (): Validates if the stack is empty.

Ex:

Stack s = new Stack(); //Creating Stack


s.Push("So"); //Adding elements into Stack
s.Push("This");
s.Push("Is");
s.Push("How");
s.Push("Queues");
s.Push("Work");

s.Peek(); // To get the Top most element (finally inserted) without removing it.
Output : Work

IEnumerator IE = s.GetEnumerator();//Getting all the values and storing them in IE


while (IE.MoveNext()){ //Initially IE pointer will be set one index behind
Console.Write(IE.Current + " ");
}

Output : Work Queues How Is This So

s.Pop(); // To remove the Top most element (finally inserted element)from stack.
Output : Work

ArrayList:
An ArrayList is an array that can dynamically grow and shrink.It Implements the IList interface to
achieve this property.

Properties:

Capacity - Gets or sets the number of elements that the ArrayList can contain.
Count - Gets the number of elements contained in an ArrayList object.
IsFixedSize - Gets a value indicating whether a ArrayList object has a fixed size. A collection
with a fixed size does not allow the addition or removal of elements after the collection is
created, but does allow the modification of existing elements.
Item - Gets or sets the element at the specified index.
Ex:

public static void Main()


{
ArrayList myArraylist = new ArrayList();// create an array list
Console.WriteLine("myArraylist capacity: " + myArraylist.Capacity);
Console.WriteLine("myArraylist number of elements: "+ myArraylist.Count);
Console.WriteLine();
Output:
myArraylist capacity : 0
myArraylist number of elements: 0

Console.WriteLine("Adding 6 elements");
// Add elements to the array list
myArraylist.Add('C');
myArraylist.Add('A');
myArraylist.Add('E');
myArraylist.Add('B');
myArraylist.Add('D');
myArraylist.Add('F');

Console.WriteLine("Current capacity: " + myArraylist.Capacity);


Console.WriteLine("Number of elements: " + myArraylist.Count);

Output:
Current capacity : 6
Number of elements : 6

// Display the array list using array indexing.


Console.Write("Current contents: ");
for (int i = 0; i < myArraylist.Count; i++)
Console.Write(myArraylist[i]+ " ");
Console.WriteLine("\n");

Output:
C A E B D F

myArraylist.Sort();//Sorting the array list

Console.Write("After Sorting: ");


for (int i = 0; i < myArraylist.Count; i++)
Console.Write(myArraylist[i] + " ");
Console.WriteLine("\n");

Output:
A B C D E F

Console.WriteLine("Removing 2 elements");
// Remove elements from the array list.
myArraylist.Remove('C');
myArraylist.Remove('B');
Console.WriteLine("Current capacity: " + myArraylist.Capacity);
Console.WriteLine("Number of elements: " + myArraylist.Count);

Output:
Current capacity : 8
Number of elements : 4

// Use foreach loop to display the list.


Console.Write("Contents: ");
foreach (char c in myArraylist)
Console.Write(c + " ");
Console.WriteLine("\n");

Output:
A D E F

Console.WriteLine("Adding 10 more elements");


// Add enough elements to force myArraylist to grow.
for (int i = 0; i < 10; i++)
myArraylist.Add((char)('a' + i));
Console.WriteLine("Current capacity: " + myArraylist.Capacity);
Console.WriteLine("Number of elements: " + myArraylist.Count);
Console.Write("Contents: ");
foreach (char c in myArraylist)
Console.Write(c + " ");
Console.WriteLine("\n");

Output:
Current capacity : 16
Number of elements : 14
A D E F a b c d e f g h i j

// Change contents using array indexing.


Console.WriteLine("Change first three elements");
myArraylist[0] = 'X';
myArraylist[1] = 'Y';
myArraylist[2] = 'Z';
Console.Write("Contents: ");
foreach (char c in myArraylist)
Console.Write(c + " ");
Console.WriteLine();
Output:
X Y Z F a b c d e f g h i j

Console.ReadLine();
}

ArrayList.FixedSize Method:
(If edited or deleted in fixed arraylist, it’s reflected in parent arraylist)

public static void Main() {


// Creates and initializes a new ArrayList.
ArrayList myAL = new ArrayList();
myAL.Add("The");
myAL.Add("quick");
myAL.Add("brown");
myAL.Add("fox");

// Create a fixed-size wrapper around the ArrayList.


ArrayList myFixedSizeAL = ArrayList.FixedSize(myAL);

// Display whether the ArrayLists have a fixed size or not.


Console.WriteLine("myAL{0}.", myAL.IsFixedSize?"has fixed size":"variable size");
Console.WriteLine("myFixedSizeAL {0}.", myFixedSizeAL.IsFixedSize ? "has a fixed
size" : "does not have a fixed size");

// Display both ArrayLists.


Console.WriteLine("Initially,");
Console.Write("Standard :");
PrintValues(myAL, ' ');
Console.Write("Fixed size:");
PrintValues(myFixedSizeAL, ' ');

myFixedSizeAL.Sort();// Sort is allowed in the fixed-size ArrayList

// Display both ArrayLists.


Console.WriteLine("After Sort,");
Console.Write("Standard :");
PrintValues(myAL, ' ');
Console.Write("Fixed size:");
PrintValues(myFixedSizeAL, ' ');

myFixedSizeAL.Reverse();// Reverse is allowed in the fixed-size ArrayList.

// Display both ArrayLists.


Console.WriteLine("After Reverse,");
Console.Write("Standard :");
PrintValues(myAL, ' ');
Console.Write("Fixed size:");
PrintValues(myFixedSizeAL, ' ');

// Add an element to the standard ArrayList.


myAL.Add("AddMe");

// Display both ArrayLists.


Console.WriteLine("After adding to the standard ArrayList,");
Console.Write("Standard :");
PrintValues(myAL, ' ');
Console.Write("Fixed size:");
PrintValues(myFixedSizeAL, ' ');
Console.WriteLine();

// Adding or inserting elements to the fixed-size ArrayList throws an exception.


try {
myFixedSizeAL.Add("AddMe2");
}
catch (Exception myException) {
Console.WriteLine("Exception: " + myException.ToString());
}
try {
myFixedSizeAL.Insert(3, "InsertMe");
}
catch (Exception myException){
Console.WriteLine("Exception: " + myException.ToString());
}
Console.ReadLine();
}

public static void PrintValues(IEnumerable myList, char mySeparator) {


foreach (Object obj in myList)
Console.Write("{0}{1}", mySeparator, obj);
Console.WriteLine();
}
}

Output:

myAL does not have a fixed size.


myFixedSizeAL has a fixed size.

Initially,
Standard : The quick brown fox
Fixed size: The quick brown fox
After Sort,
Standard : brown fox quick The
Fixed size: brown fox quick The
After Reverse,
Standard : The quick fox brown
Fixed size: The quick fox brown
After adding to the standard ArrayList,
Standard : The quick fox brown AddMe
Fixed size: The quick fox brown AddMe

Exception: System.NotSupportedException: Collection was of a fixed size.at


System.Collections.FixedSizeArrayList.Add(Object obj)at SamplesArrayList.Main()
Exception: System.NotSupportedException: Collection was of a fixed size.
at System.Collections.FixedSizeArrayList.Insert(Int32 index, Object obj)
at SamplesArrayList.Main()

Hashtable:
Represents a collection of key/value pairs that are organized based on the hash code of the key.
A key cannot be a null reference but should be a value.

Initializing Hashtable:

Hashtable Htable1 = new Hashtable() ; //Default one


Hashtable Htable2 = new Hashtable(10); // capacity or size.
Hashtable Htable3 = new Hashtable(10 ,06); //capacity , loadfactor
Loadfactor: This factor helps a lot if you looking for performance, The smaller the load size
(fraction of the tashtable full .6 means 60% full) , the more efficiently our hash table works and
but it occupies more memory.

Create a Hashtable
Hashtable myHashTable = new Hashtable();
Add some data in it.
myHashTable.Add("Key1", "Value1");
myHashTable.Add("Key2", "Value2");
Get the size.
myHashTable.Count; // an int value.
Now to fetch data
Create an object of IDictionaryEnumerator, this is an interface that creates an enumerator
and customized for Dictionary objects.

IDictionaryEnumerator IDEnu = myHashTable.GetEnumerator();


while ( IDEnu.MoveNext()) {
myString += IDEnu.Key + " ";
myString += IDEnu.Value ;
}
Clear hash table...
myHashTable.Clear();
Search for a specific key: remember its value type when used

if (myHashTable.ContainsKey("Key1")) {
Console.WriteLine("Key1 is present");
}
Search for a specific key: remember its value type when used

if (myHashTable.ContainsValue("Value1")) {
Console.WriteLine("Value1 is present");
}
Using Key to get Value:

public static void Main()


{
Hashtable Htable1 = new Hashtable();
Htable1.Add("rajesh", "111");
Htable1.Add("praveen", "017");
Htable1.Add("nara", "001");

IDictionaryEnumerator IDEnu = Htable1.GetEnumerator();


while (IDEnu.MoveNext())
{
if (IDEnu.Key.Equals("rajesh"))
{
string y = IDEnu.Value.ToString();
}
}
}

Output: y=111
When to Use Generic Collections:
Using generic collections is generally recommended, because you gain the immediate benefit of
type safety without having to derive from a base collection type and implement type-specific
members. In addition, generic collection types generally perform better than the corresponding
nongeneric collection types (and better than types derived from nongeneric base collection types)
when the collection elements are value types, because with generics there is no need to box the
elements.

The following generic types correspond to existing collection types:

* List is the generic class corresponding to ArrayList.

* Dictionary is the generic class corresponding to Hashtable.

* Collection is the generic class corresponding to CollectionBase. Collection can be used as a


base class, but unlike CollectionBase it is not abstract, making it much easier to use.

* ReadOnlyCollection is the generic class corresponding to ReadOnlyCollectionBase.


ReadOnlyCollection is not abstract, and has a constructor that makes it easy to expose an
existing List as a read-only collection.

* The Queue, Stack, and SortedList generic classes correspond to the respective nongeneric
classes with the same names.

Additional Types

There are several generic collection types that do not have nongeneric counterparts:

* LinkedList is a general-purpose linked list that provides O(1) insertion and removal operations.

* SortedDictionary is a sorted dictionary with O(log n) insertion and retrieval operations, making
it a useful alternative to SortedList.
* KeyedCollection is a hybrid between a list and a dictionary, which provides a way to store
objects that contain their own keys.

Additional Functionality

Some of the generic types have functionality not found in the nongeneric collection types. For
example, the List class, which corresponds to the nongeneric ArrayList class, has a number of
methods that accept generic delegates, such as the Predicate delegate that allows you to specify
methods for searching the list, the Action delegate that represents methods that act on each
element of the list, and the Converter delegate that lets you define conversions between types.

The List class allows you to specify your own IComparer generic interface implementations for
sorting and searching the list. The SortedDictionary and SortedList classes also have this
capability, and in addition allow the comparers to be specified when the collection is created. In
similar fashion, the Dictionary and KeyedCollection classes allow you to specify your own
equality comparers

Selecting a Collection Class


Be sure to choose your System.Collections class carefully. Using the wrong type can restrict your
use of the collection.

Consider the following questions:

** Do you need a sequential list where the element is typically discarded after its value is
retrieved?

If yes, consider using the Queue class or the Queue generic class if you need first-in-first-out
(FIFO) behavior. Consider using the Stack class or the Stack generic class if you need last-in-
first-out (LIFO) behavior. If not, consider using the other collections.

** Do you need to access the elements in a certain order, such as FIFO, LIFO, or random?

The Queue class and the Queue generic class offer FIFO access.

The Stack class and the Stack generic class offer LIFO access.

The LinkedList generic class allows sequential access either from head to Tail or from Tail to
Head.

The rest of the collections offer random access.

** Do you need to access each element by index?

The ArrayList and StringCollection classes and the List generic class offer access to their
elements by the zero-based index of the element.

The Hashtable, SortedList, ListDictionary, and StringDictionary classes, and the Dictionary and
SortedDictionary generic classes offer access to their elements by the key of the element.

The NameObjectCollectionBase and NameValueCollection classes, and the KeyedCollection and


SortedList generic classes offer access to their elements by either the zero-based index or the
key of the element.

** Will each element contain one value, a combination of one key and one value, or a
combination of one key and multiple values?

One value: Use any of the collections based on the IList interface or the IList generic interface.

One key and one value: Use any of the collections based on the IDictionary interface or the
IDictionary generic interface.
One value with embedded key: Use the KeyedCollection generic class.

One key and multiple values: Use the NameValueCollection class.

** Do you need to sort the elements differently from how they were entered?

The Hashtable class sorts its elements by their hash codes.

The SortedList class and the SortedDictionary and SortedList generic classes sort their
elements by the key, based on implementations of the IComparer interface and the IComparer
generic interface.

ArrayList provides a Sort method that takes an IComparer implementation as a parameter.


Its generic counterpart, the List generic class, provides a Sort method that takes an
implementation of the IComparer generic interface as a parameter.

** Do you need fast searches and retrieval of information?

ListDictionary is faster than Hashtable for small collections (10 items or fewer). The
SortedDictionary generic class provides faster lookup than the Dictionary generic class.

** Do you need collections that accept only strings?

StringCollection (based on IList) and StringDictionary (based on IDictionary) are in the


System.Collections.Specialized namespace.

In addition, you can use any of the generic collection classes in the System.Collections.Generic
namespace as strongly typed string collections by specifying the String class for their generic
type arguments.

Generics:
Generics in C# used to create Type Safe collection.

Built in Generic collection classes are List ,Queue,Stack,Dictionary,etc.

List<string> strlist = new List<string>(); // Arraylist in Nongeneric collection


Queue<int> intqueue = new Queue<int>();
Stack<double> dbStack = new Stack<double>();
Dictionary<string, int> strKeyintVal = new Dictionary<string, int>();//HashTable
Using a Generic Class :

using System;
using System.Collections.Generic;

namespace GenClass
{
public class GenClass<T>
{
T t;
public T Val
{
get { return t; }
set { t = value;}
}
}
public class GenClassMain
{
public static void Main()
{
//create a string version of our generic class
GenClass<string> mystring = new GenClass<string>();
//set the value
mystring.Val = "hello";

//output that value


System.Console.Write(mystring.Val);
//output the value's type
System.Console.Write(" - {0} ; ",mystring.Val.GetType());

//create another instance of our generic class, using a different type


GenClass<int> myint = new GenClass<int>();
//load the value
myint.Val = 5;
//output the value
System.Console.Write(myint.Val);
//output the value's type
System.Console.Write(" - {0}",myint.Val.GetType());
}
}
}
Outout: hello - System.String ; 5 – System.Int32

Using a Generic List of Class :

using System;
using System.Collections.Generic;
namespace GenericList
{
public class Person
{
private string name;
private int age;
public string Name
{
get{return name;}
set{name = value;}
}
public int Age
{
get{return age;}
set{age = value;}
}
public static void Main()
{
// now create a collection using the new Generic List
List<Person> employees = new List<Person>();
//now add a couple of generic person objects to the generic collection
Person p1 = new Person();
p1.Name = "John";
p1.Age = 23;
employees.Add(p1);

Person p2 = new Person();


p2.Name = "James";
p2.Age = 34;
employees.Add(p2);

// now we have a type-safe collection of objects with the


// richness of Intellisense built in
// print out the contents of the collection
foreach (Person p in employees)
{
Console.WriteLine(String.Format("{0} - {1}", p.Name, p.Age));
}
}
}
}

Default keyword in generics:


Public MyGenericClass ()
{
innerT1Object = default (T1);
}

The result of this is that innerT1Object is assigned a value of null if it is a reference type or a default
value if it is a value type. This default value is 0 for numeric types, while structs have each of their
members initialized to 0 or null in the same way.

Early Binding & Late Binding:


Early binding: Declaring the Object of specific type.

Late binding: Declaring the object of generic type.


Early binding: Properties and method can be identified by compile time. An object is early
bound when it is assigned to a variable declared to be of a specific object type. Early bound
objects allow the compiler to allocate memory and perform other optimizations before an
application executes.

Ex: FileStream FS = new FileStream("C:\\tmp.txt", System.IO.FileMode.Open);

Because FileStream is a specific object type, the instance assigned to FS is early bound.

Late binding: Properties and method can be identified by Run time. An object is late bound
when it is assigned to a variable declared to be of type Object. Objects of this type can hold
references to any object, but lack many of the advantages of early-bound objects.

For example, the following code fragment declares an object variable to hold an object returned
by the CreateObject function:

void TestLateBinding()
{
object xlApp;
object xlBook;
object xlSheet;
xlApp = CreateObject("Excel.Application");
xlBook = xlApp.Workbooks.Add;
xlSheet = xlBook.Worksheets(1);
xlSheet.Activate();
xlSheet.Application.Visible = true;
xlSheet.Cells(2, 2) = "This is column B row 2";
}

Advantages of Early Binding:

* Early Binding they allow the compiler to make important optimizations that yield more efficient
applications.

* Early-bound objects are significantly faster than late-bound objects and make your code easier
to read and maintain by stating exactly what kind of objects are being used.

* Another advantage to early binding is that it enables useful features such as automatic code
completion and Dynamic Help because the Visual Studio integrated development environment
(IDE) can determine exactly what type of object you are working with as you edit the code.

* Early binding reduces the number and severity of run-time errors because it allows the
compiler to report errors when a program is compiled.
Advantages of Late Binding:

* The main advantage is that code which uses late binding is more certain to be version-
independent

* The more references your project contains, the larger the file size and the longer it takes to
compile.

* Some programming environments don't allow you to create references to another application.

TypeOf:
You can use the "typeof" operator to obtain information about a type.
The typeof operator returns a System.Type object for a given type.
The typeof operator has this general form: typeof(type)
type is the type being obtained.
The System.Type object returned encapsulates the information associated with type.

Serialization:
Serialization is a process of taking an object and converting into a form so that it can be
transported across the network or can be persisted in the storage location. This storage location
can be physical file, database or ASP.NET Cache. The form contains the state of the object so
that by this format, we can construct the same object a later point in time, which is called
Deserialization.

There are three formats of serialization

Binary Serialization : Light and compact used in Remoting


SOAP Serialization : Interoperable used in SOAP and web Services
XML Serialization : Custom Serialization

XMLSerialization: (Shallow Serialization)


For XML serialization, we need to use the attributes and specify them for each and every public
member that is need. But since it is limited that it can serialize only public members, Serialization
done by it is called custom serialization. It is also known as Shallow Serialization
SOAP and Binary Serialization: (Deep Serialization)
SOAP or Binary serialization is used when it is needed to transport data across the network.
SOAP sends it using HTTP Protocol which makes it most interoperable while Binary serialization is
known for its light and compact nature.
Web Services uses the SOAP Serialization and Remoting uses the Binary Serialization.
Advantage of using the SOAP or Binary serialization is that you can serialize the entire object and
all those object that are being referenced by it. This is why it is also called Deep Serialization.
If you want any class to serialize through any of these methods then you should use
[Serializable] attribute on that class and then you can use the SoapFormater class or
BinaryFormatter class to do the serialization.
These classes have Serialize and DeSerialize method.
If you will not use Serializable Attribute for the class, then it will raise the exception.

Example:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace ObjectStore
{
[Serializable]
public class Product
{
public long Id;
public string Name;
public double Price;

[NonSerialized]
string Notes;
public Product(long id, string name, double price, string notes) {
Id = id;
Name = name;
Price = price;
Notes = notes;
}
public override string ToString() {
return string.Format("{0}: {1} (${2:F2}) {3}", Id, Name, Price, Notes);
}
}
public class Program {
static void Main(string[] args){
try
{ // Create products.
List<Product> products = new List<Product>();
products.Add(new Product(1, "Spiky Pung", 1000.0, "Good stuff."));
products.Add(new Product(2, "Gloop Galloop Soup", 25.0, "Tasty."));
products.Add(new Product(4, "Hat Sauce", 12.0, "One for the kids."));
Console.WriteLine("Products to save:");
foreach (Product product in products) {
Console.WriteLine(product);
}
Console.WriteLine();

// Note: IFormatter Provides functionality for formatting serialized objects.


// All formatters must implement this interface.
// IFormatter has classes BinaryFormatter; SoapFormatter and Formatter
// Use Serialize to serialize an object or graph of objects.
// Use Deserialize to deserialize a stream and create a clone of the original object

IFormatter serializer = new BinaryFormatter();// Get serializer.


// Serialize products.
FileStream saveFile = new FileStream("Products.bin", FileMode.Create);
serializer.Serialize(saveFile, products);
saveFile.Close();

// Deserialize products.
FileStream loadFile = new FileStream("Products.bin", FileMode.Open);
List<Product> savedProducts =
serializer.Deserialize(loadFile) as List<Product>;
loadFile.Close();
Console.WriteLine("Products loaded:");
foreach (Product product in savedProducts) {
Console.WriteLine(product);
}
}
catch (SerializationException e){
Console.WriteLine("A serialization exception has been thrown!");
Console.WriteLine(e.Message);
}
catch (IOException e) {
Console.WriteLine("An IO exception has been thrown!");
Console.WriteLine(e.ToString());
}

Console.ReadKey();
}
}
}

Though this is the easiest way but at time you need the way so that you can decide what fields to
serialize and how the serialization actually occurs. You can implement the ISerializable interface
in the class. You need two things for that

1. Constructor that is overridden and can handle the Deserialization process


2. GetObject method that tracks about which data is serialized.
Define Serialization functions:
Now we need two functions: One to say how to serialize objects and another to say how to
deserialize them. For serialization we override the GetObjectData () function provided by the
ISerializable interface. For deserialization we provide a special constructor with the serialization
parameters as arguments. This constructor will be called when we deserialize our file to object.

One of the important parameters is the SerializationInfo object. This object holds a name-value
pair for the properties to be serialized. You can decide which property should be serialized and
which not in the GetObjectData () function. All the properties that are added to this
SerializationInfo parameter will be serialized. Here are the codes for the two functions. Add them
to our Employee class.

Example:

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace MyObjSerial
{
[Serializable()]//Set this attribute to all the classes that want to serialize
public class Employee : ISerializable //derive your class from ISerializable
{
public int EmpId;
public string EmpName;

public Employee() //Default constructor


{
EmpId = 0; EmpName = null;
}

//Deserialization constructor.
public Employee(SerializationInfo info, StreamingContext ctxt)
{
//Get the values from info and assign them to the appropriate properties
EmpId = (int)info.GetValue("EmployeeId", typeof(int));
EmpName = (String)info.GetValue("EmployeeName", typeof(string));
}

//Serialization function.
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
//You can use any custom name for your name-value pair.
//But make sure you read the values with the same name.If you write EmpId
as "EmployeeId" then you should read the same with "EmployeeId"
info.AddValue("EmployeeId", EmpId);
info.AddValue("EmployeeName", EmpName);
}
}

public class ObjSerial


{
public static void Main(String[] args)
{
//Create a new Employee object
Employee mp = new Employee();
mp.EmpId = 111;
mp.EmpName = "Rajesh";

//Serialization
// Open a file and serialize the object into it in binary format.
// EmployeeInfo.osl is the file that we are creating.
// Note:- you can give any extension you want for your file
Stream stream = File.Open("EmployeeInfo.xxx", FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();

Console.WriteLine("Writing Employee Information");


bformatter.Serialize(stream, mp);
stream.Close();

//Deserialization
mp = null; //Clear mp for further usage.

//Open the file written above and read values from it.
stream = File.Open("EmployeeInfo.xxx", FileMode.Open);
bformatter = new BinaryFormatter();

Console.WriteLine("Reading Employee Information");


mp = (Employee)bformatter.Deserialize(stream);
stream.Close();

Console.WriteLine("Employee Id: {0}",mp.EmpId.ToString());


Console.WriteLine("Employee Name: {0}",mp.EmpName);
}
}
}

Introduction to .NET Assemblies

What is an assembly?

• An Assembly is a logical unit of code


• Assembly physically exist as DLLs or EXEs
• One assembly can contain one or more files
• The constituent files can include any file types like image files, text files etc. along with
DLLs or EXEs
• When you compile your source code by default the exe/dll generated is actually an
assembly
• Unless your code is bundled as assembly it can not be used in any other application
• When you talk about version of a component you are actually talking about version of the
assembly to which the component belongs.
• Every assembly file contains information about itself. This information is called as
Assembly Manifest.
What is assembly manifest?

• Assembly manifest is a data structure which stores information about an assembly


• This information is stored within the assembly file(DLL/EXE) itself
• The information includes version information, list of constituent files etc.

What is private and shared assembly?

The assembly which is used only by a single application is called as private assembly. Suppose
you created a DLL which encapsulates your business logic. This DLL will be used by your client
application only and not by any other application. In order to run the application properly your
DLL must reside in the same folder in which the client application is installed. Thus the assembly
is private to your application.

Suppose that you are creating a general purpose DLL which provides functionality which will be
used by variety of applications. Now, instead of each client application having its own copy of DLL
you can place the DLL in 'global assembly cache'. Such assemblies are called as shared
assemblies.

What is Global Assembly Cache?

Global assembly cache is nothing but a special disk folder where all the shared assemblies will be
kept. It is located under <drive>:\WinNT\Assembly folder.

How assemblies avoid DLL Hell?

As stated earlier most of the assemblies are private. Hence each client application refers
assemblies from its own installation folder. So, even though there are multiple versions of same
assembly they will not conflict with each other. Consider following example:

• You created assembly Assembly1


• You also created a client application which uses Assembly1 say Client1
• You installed the client in C:\MyApp1 and also placed Assembly1 in this folder
• After some days you changed Assembly1
• You now created another application Client2 which uses this changed Assembly1
• You installed Client2 in C:\MyApp2 and also placed changed Assembly1 in this folder
• Since both the clients are referring to their own versions of Assembly1 everything goes on
smoothly

Now consider the case when you develop assembly that is shared one. In this case it is important
to know how assemblies are versioned. All assemblies have a version number in the form:

major.minor.build.revision

If you change the original assembly the changed version will be considered compatible with
existing one if the major and minor versions of both the assemblies match.

When the client application requests assembly the requested version number is matched against
available versions and the version matching major and minor version numbers and having latest
build and revision numbers are supplied.
How do I create shared assemblies?

Following steps are involved in creating shared assemblies :

• Create your DLL/EXE source code


• Generate unique assembly name using SN utility
• Sign your DLL/EXE with the private key by modifying AssemblyInfo file
• Compile your DLL/EXE
• Place the resultant DLL/EXE in global assembly cache using AL utility

How do I create unique assembly name?

Microsoft now uses a public-private key pair to uniquely identify an assembly. These keys are
generated using a utility called SN.exe (SN stands for shared name). The most common syntax of
is :

sn -k mykeyfile.snk

Where k represents that we want to generate a key and the file name followed is the file in which
the keys will be stored.

How do I sign my DLL/EXE?

Before placing the assembly into shared cache you need to sign it using the keys we just
generated. You mention the signing information in a special file called AssemblyInfo. Open the
file from VS.NET solution explorer and change it to include following lines :

[assembly:AssemblyKeyFile("file_path")]

Now recompile the project and the assembly will be signed for you.

Note : You can also supply the key file information during command line compilation via
/a.keyfile switch.

How do I place the assembly in shared cache?

Microsoft has provided a utility called gacutil.exe to actually place your assembly in shared cache.

gacutil /i:my_dll.dll

Now your dll will be placed at proper location by the utility.

Hands On...

Now, that we have understood the basics of assemblies let us apply our knowledge by developing
a simple shared assembly.

In this example we will create a VB.NET component called SampleGAC (GAC stands for Global
Assembly Cache). We will also create a key file named sample.key. We will sign our component
with this key file and place it in Global Assembly Cache.
• Step 1 : Creating our sample component

Here is the code for the component. It just includes one method which returns a string.

Imports system

namespace BAJComponents
public class Sample
public function GetData () as string
return "hello world"
end function
end class
end namespace

• Step 2 : Generate a key file

To generate the key file issue following command at command prompt.

sn -k sample.key

This will generate the key file in the same folder

• Step 3 : Sign your component with the key

Now, we will sign the assembly with the key file we just created.

Vbc sampleGAC.vb /t:library /a.keyfile:sample.key

• Step 4 : Host the signed assembly in Global Assembly Cache

We will use gacutil utility to place the assembly in Global Assembly Cache.

Prompt gacutil.exe -i assemblyname.dll (assembly full path)

After hosting the assemblies just go to WINNT\Assembly folder and you will find your assembly
listed there. Note how the assembly folder is treated differently that normal folders.

Create a separate folder and copy this assembly in that folder. Then open Machine config file in
the path C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG and add the assembly in
that file .Then this dll will be accessible for add reference. On adding even though it shows as if
the path is local folder, its adds the file from GAC while runtime.

• Step 5 : Test that our assembly works

Now, we will create a sample client application which uses our shared assembly. Just create a
sample code as listed below:

Imports system
Imports BAJComponents
public class SampleTest
shared sub main ()
dim x as new sample
dim s as string="x".getdata ()
console.writeline(s)
end sub
end class

Compile above code using:

Vbc sampletest.vb /t:exe /r:<assembly_dll_path_here>

Now, copy the resulting EXE in any other folder and run it. It will display "Hello World" indicating
that it is using our shared assembly.

Pickling:

When the file is compiled, any attributes defined for assembly in Assemblyinfo.cs file are saved
into the resulting assembly — this process is known as pickling.

Delegates:
* A delegate is a type that enables you to store references to functions.
* Delegates are declared like functions, without function body and using the delegate keyword
* The delegate declaration specifies a function signature consisting of a return type and the
parameter list.
* After defining a delegate, we can declare a variable with the type of that delegate. We can then
initialize this variable as a reference to any function that has the same signature as that of
delegate. Then we call that function by using the delegate variable as if it were a function.
* We can pass a delegate variable to a function as a parameter, then that function can use the
delegate to call whatever function it refers to, without having knowledge as to what function will
be called until runtime.

Ex:
class Program
{
delegate int mydelegate(int x, int y);

static int add(int a, int b)


{
return a + b;
}
static int sub(int a, int b)
{
return a - b;
}

static void Main(string[] args)


{
mydelegate mydel;
int x = 5, y = 6;
mydel = new mydelegate(add); // If not static p.add ,where p is object
int z = mydel(x, y);
mydel = new mydelegate(sub);
int z1 = mydel(x, y);
}
}

Throw:
The throw statement is used to signal the occurrence of an anomalous situation
(exception) during the program execution. Usually the throw statements are used with try-catch
or try-finally statements. When an exception is thrown, the program looks for the catch
statement that handles this exception.

try . . . catch . . . finally

The C# language includes syntax for Structured Exception Handling (SEH). Keywords exist to
mark code out as being able to handle exceptions, along with instructions as to what to do if an
exception occurs. The three keywords you use for this are try, catch, and finally. Each of these
has an associated code block and must be used in consecutive lines of code. The basic structure
is as follows:

try
{
...
}
catch (<exceptionType> e)
{
...
}
finally
{
...
}
It is also possible, however, to have a try block and a finally block with no catch block, or a try
block with multiple catch blocks. If one or more catch blocks exist, then the finally block is
optional, else it is mandatory.

The usage of the blocks is as follows:

• try: Contains code that might throw exceptions (throw is the C# way of saying generate
or cause when talking about exceptions).
• catch: Contains code to execute when exceptions are thrown. catch blocks may be set to
respond only to specific exception types (such as System.IndexOutOfRangeException)
using <exceptionType>, hence the ability to provide multiple catch blocks. It is also
possible to omit this parameter entirely, to get a general catch block that will respond to
all exceptions.
• finally: Contains code that is always executed, either after the try block if no exception
occurs, after a catch block if an exception is handled, or just before an unhandled
exception terminates the application (the fact that this block is processed at this time is
the reason for its existence; otherwise, you might just as well place code after the block).

The sequence of events that occurs after an exception occurs in code in a try block is:

• The try block terminates at the point where the exception occurred.
• If a catch block exists, then a check is made to see if the block matches the type of
exception that has been thrown. If no catch block exists, then the finally block (which
must be present if there are no catch blocks) executes.
• If a catch block exists, but there is no match, then a check is made for other catch blocks.
• If a catch block matches the exception type, the code it contains executes, and then the
finally block executes if it is present.
• If no catch blocks match the exception type, then the finally block of code executes if it is
present.

MessageBox

if(MessageBox.Show("Really delete?", "Confirm delete", MessageBoxButtons.YesNo) ==


DialogResult.Yes)
{
label1.Text = "u r deleted";
}

You might also like