dotnet_basics at a glance

91
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 {

Upload: rajesh

Post on 19-Nov-2014

122 views

Category:

Documents


0 download

DESCRIPTION

Basics on C# DotNet

TRANSCRIPT

Page 1: DotNet_Basics at a Glance

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 } }}/////////////////////////////////////////////////////

Page 2: DotNet_Basics at a Glance

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.

Page 3: DotNet_Basics at a Glance

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".

Page 4: DotNet_Basics at a Glance

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();

Page 5: DotNet_Basics at a Glance

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.

Page 6: DotNet_Basics at a Glance

} }

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 } }}

Page 7: DotNet_Basics at a Glance

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 } }

Page 8: DotNet_Basics at a Glance

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(); } }

Outputp1: x=11, y=21, z=32p2: x=55, y=25, z=24

CommentsIn the preceding example, if you use a statement like this:

p2.y = 66; // Error you will get the compiler error message:

Checked and UnCheckedChecked keyword throws an error if the value converted does not fit into the type while explicit conversion.

byte destinationVar; short sourceVar = 281;

Page 9: DotNet_Basics at a Glance

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 classesEx:

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.

Page 10: DotNet_Basics at a Glance

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

Page 11: DotNet_Basics at a Glance

{

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 {

Page 12: DotNet_Basics at a Glance

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.

Page 13: DotNet_Basics at a Glance

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.

Page 14: DotNet_Basics at a Glance

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

myDerivedClass obj = new myDerivedClass (15)

Then the sequence of execution will be1. 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

Page 15: DotNet_Basics at a Glance

{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.

Page 16: DotNet_Basics at a Glance

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.

Page 17: DotNet_Basics at a Glance

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

Page 18: DotNet_Basics at a Glance

{

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() {}}

Page 19: DotNet_Basics at a Glance

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.

Page 20: DotNet_Basics at a Glance

* 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 Classesusing 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; } }

Page 21: DotNet_Basics at a Glance

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.

Page 22: DotNet_Basics at a Glance

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

Page 23: DotNet_Basics at a Glance

only declaration is allowed with implementation

3. Fields or variables are not allowed in Interface

Variables are allowed in Abstract classes

4. Access Modifiers are not allowed in Interfaces

Access Modifiers are allowed in abstract class

5. All the members of Interface should be implemented in the derived class

Only the members marked as Abstract need to be implemented in the derived class

6. If we add new method to an interface we need to track down all the inherited

classes and implement these methods

If new methods are added they can be implemented in the class itself so no need to

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: 1 2 3 5

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

Page 24: DotNet_Basics at a Glance

*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 errorint x = 1;// variable going to be passed as valueConsole.Write("From the main: ");Console.Write(refx);Console.Write(" , ");Console.WriteLine(x);Method(ref refx, x); // sending refx as ref and x as valueConsole.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 methodFrom 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:

Page 25: DotNet_Basics at a Glance

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.

Page 26: DotNet_Basics at a Glance

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] + " "); } }

Page 27: DotNet_Basics at a Glance

}

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.

Page 28: DotNet_Basics at a Glance

* 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.

Page 29: DotNet_Basics at a Glance

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 22In 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.

Page 30: DotNet_Basics at a Glance

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 membersusing 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); }

Page 31: DotNet_Basics at a Glance

}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);

Page 32: DotNet_Basics at a Glance

}}

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

Page 33: DotNet_Basics at a Glance

{ 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

Page 34: DotNet_Basics at a Glance

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:

Page 35: DotNet_Basics at a Glance

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.

Page 36: DotNet_Basics at a Glance

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; }

Page 37: DotNet_Basics at a Glance

} }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 were public data members.

Allows methods on an object to be called as though 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 a property has no parameters.A get accessor of an indexer has the same formal parameter list as the indexer.

A set accessor of a property contains the implicit value parameter.

A set accessor of an indexer has the same formal parameter list as the indexer, in addition to the value 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

Page 38: DotNet_Basics at a Glance

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]

Page 39: DotNet_Basics at a Glance

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:

Page 40: DotNet_Basics at a Glance

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.

Page 41: DotNet_Basics at a Glance

Enum: Enum is a complex type of variable which can take one of a fixed set of results. Defining EnumerationsEnumerations 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 withtypeName 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:

Page 42: DotNet_Basics at a Glance

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 {

Page 43: DotNet_Basics at a Glance

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: ");

Page 44: DotNet_Basics at a Glance

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() {

Page 45: DotNet_Basics at a Glance

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 ArraysArrays are declared in the following way:<baseType>[] <name>;Ex:

int[] myIntArray = new int[5]; //orint[] 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 matchint[] 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>)

Page 46: DotNet_Basics at a Glance

{ // 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 arraychar[] myChars = myString.ToCharArray();

int a = myString.Length; // a = 8string b = myString.ToLower(); // b = a stringstring c = myString.ToUpper(); // c = A STRINGstring 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 indexstring 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 leftstring 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:

Page 47: DotNet_Basics at a Glance

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

Page 48: DotNet_Basics at a Glance

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

Page 49: DotNet_Basics at a Glance

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

ArrayList Implements the IList interface using an array whose size is dynamically increased as required.

BitArrayManages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0).

CaseInsensitiveComparer Compares two objects for equivalence, ignoring the case of strings.

CaseInsensitiveHashCodeProvider

Supplies a hash code for an object, using a hashing algorithm that ignores the case of strings.

CollectionBase Provides the abstract base class for a strongly typed collection.

Comparer Compares two objects for equivalence, where string comparisons are case-sensitive.

DictionaryBase Provides the abstract base class for a strongly typed collection of key/value pairs.

Hashtable Represents a collection of key/value pairs that are organized based on the hash code of the key.

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

ReadOnlyCollectionBase Provides the abstract base class for a strongly typed non-generic read-only collection.

SortedList Represents a collection of key/value pairs that are sorted

Page 50: DotNet_Basics at a Glance

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

Stack Represents a simple last-in-first-out (LIFO) non-generic collection of objects.

Interfaces

  Interface Description

ICollection Defines size, enumerators, and synchronization methods for all 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.

IEnumerable Exposes the enumerator, which supports a simple iteration over a non-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.

IList Represents a non-generic collection of objects that can be individually 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.

Page 51: DotNet_Basics at a Glance

Initialization of Queue: (Have 4 overloaded methods)

Queue q0 = new Queue(); // Initializes an empty queueQueue q1 = new Queue(ICollection q0);// Copies the collection object q0 to q1Queue q2 = new Queue(5); //Initializes queue with initial capacity of 5Queue 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 Queueobject 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

Page 52: DotNet_Basics at a Glance

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 queueqarray = q.ToArray(); //Copies all the elements of q to qarray (Len becomes q len)bool y = q.IsSynchronized;// returns whether the queue is synchronizedq.CopyTo(qarray, 2); //Copies all the elements of q to qarray (Len remains) object o1 = q.Clone(); //creates a shallow copy of the queuebool x = q.Contains(" "); //checks and returns whether specified object is presentq.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 Stacks.Push("So"); //Adding elements into Stacks.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 IEwhile (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

Page 53: DotNet_Basics at a Glance

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

Page 54: DotNet_Basics at a Glance

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:

Page 55: DotNet_Basics at a Glance

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 :");

Page 56: DotNet_Basics at a Glance

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 TheAfter Reverse,Standard : The quick fox brownFixed size: The quick fox brownAfter adding to the standard ArrayList,Standard : The quick fox brown AddMeFixed 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()

Page 57: DotNet_Basics at a Glance

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()) {

Page 58: DotNet_Basics at a Glance

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

Page 59: DotNet_Basics at a Glance

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.

Page 60: DotNet_Basics at a Glance

** 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

Page 61: DotNet_Basics at a Glance

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

Page 62: DotNet_Basics at a Glance

{ 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.

Page 63: DotNet_Basics at a Glance

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.

Page 64: DotNet_Basics at a Glance

* 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 RemotingSOAP Serialization : Interoperable used in SOAP and web ServicesXML Serialization : Custom Serialization

XMLSerialization: (Shallow Serialization)

Page 65: DotNet_Basics at a Glance

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>();

Page 66: DotNet_Basics at a Glance

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 process2. GetObject method that tracks about which data is serialized.

Page 67: DotNet_Basics at a Glance

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

Page 68: DotNet_Basics at a Glance

{ 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.

Page 69: DotNet_Basics at a Glance

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?

Page 70: DotNet_Basics at a Glance

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

Page 71: DotNet_Basics at a Glance

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)

Page 72: DotNet_Basics at a Glance

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); } }

Page 73: DotNet_Basics at a Glance

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:

Page 74: DotNet_Basics at a Glance

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";}