Professional Documents
Culture Documents
Notes C
Notes C
1. What is .NET?
It is a platform neutral framework.
It is a layer between the operating system and the programming language.
It supports many programming languages, including VB.NET, C# etc.
.NET provides a common set of class libraries, which can be accessed from any .NET based
programming language. There will not be separate set of classes and libraries for each language. If you
know any one .NET language, you can write code in any .NET language.
In future versions of Windows, .NET will be freely distributed as part of operating system and users will
never have to install .NET separately.
2. What is NET?
3. “.NET is a framework”
We cannot define .NET as a ‘single thing’.
It is a new, easy, and extensive programming platform.
It is not a programming language, but it supports several programming languages.
By default .NET comes with few programming languages including C# (C Sharp), VB.NET, J# and
managed C++.
.NET is a common platform for all the supported languages. It gives a common class library, which can
be called from any of the supported languages. So, developers need not learn many libraries when they
switch to a different language. Only the syntax is different for each language.
When you write code in any language and compile, it will be converted to an ‘Intermediate Language’
(Microsoft Intermediate Language – MSIL). So, your compiled executable contains the IL and not really
executable machine language.
When the .NET application runs, the .NET framework in the target computer take care of the execution.
(To run a .NET application, the target computer should have .NET framework installed.)
The .NET framework converts the calls to .NET class libraries to the corresponding APIs of the
Operating system.
Whether you write code in C# or VB.NET, you are calling methods in the same .NET class libraries.
The same .NET framework executes the C# and VB.NET applications. So, there won’t be any
performance difference based on the language you write code.
Application
Libraries
CLR
.NET
Enterprise
Servers
.NET
Building
Block Services
C#, Visual Basic .NET
Visual Studio .NET
Windows OS (Win 32)
The MSIL and metadata are contained in a portable executable (PE) file that is based on and extends the published
Microsoft PE and Common object file format (COFF) used historically for executable content. The file format, which
accommodates MSIL or native code as well as metadata, enables the operating system to recognize common language
runtime images.
4.3 Compiling MSIL to Native Code
Before you can run Microsoft intermediate language (MSIL), it must be compiled against the common language runtime
to native code for the target machine architecture. The .NET Framework provides two ways to perform this conversion:
•A .NET Framework just-in-time (JIT) compiler.
•The .NET Framework Ngen.exe (Native Image Generator).
4.4 Compilation by the JIT Compiler
JIT compilation converts MSIL to native code on demand at application run time, when the contents of an assembly are
loaded and executed. Because the common language runtime supplies a JIT compiler for each supported CPU
architecture, developers can build a set of MSIL assemblies that can be JIT-compiled and run on different computers
with different machine architectures. However, if your managed code calls platform-specific native APIs or a
platform-specific class library, it will run only on that operating system.
JIT compilation takes into account the possibility that some code might never be called during execution. Instead of
using time and memory to convert all the MSIL in a PE file to native code, it converts the MSIL as needed during
execution and stores the resulting native code in memory so that it is accessible for subsequent calls in the context of
that process. The loader creates and attaches a stub to each method in a type when the type is loaded and initialized.
When a method is called for the first time, the stub passes control to the JIT compiler, which converts the MSIL for that
method into native code and modifies the stub to point directly to the generated native code. Therefore, subsequent
calls to the JIT-compiled method go directly to the native code.
Install-Time Code Generation Using NGen.exe
Because the JIT compiler converts an assembly’s MSIL to native code when individual methods defined in that
assembly are called, it affects performance adversely at run time. In most cases, that diminished performance is
acceptable. More importantly, the code generated by the JIT compiler is bound to the process that triggered the
compilation. It cannot be shared across multiple processes. To allow the generated code to be shared across multiple
invocations of an application or across multiple processes that share a set of assemblies, the common language
runtime supports an ahead-of-time compilation mode. This ahead-of-time compilation mode uses the Ngen.exe (Native
Image Generator) to convert MSIL assemblies to native code much like the JIT compiler does. However, the operation
of Ngen.exe differs from that of the JIT compiler in three ways:
•It performs the conversion from MSIL to native code before running the application instead of while the application is
running.
•It compiles an entire assembly at a time, instead of one method at a time.
•It persists the generated code in the Native Image Cache as a file on disk.
4.5 Summary of Managed Code Execution Process
The process of compiling and executing managed code is given below: -
1. When you compile a program developed in a language that targets the CLR, instead of compiling the source code into
machine-level code, the compiler translates it into Microsoft Intermediate Language (MSIL) or Intermediate language
(IL). This ensures language interoperability.
2. In addition to translating the code into IL, the compiler also produces metadata about the program during the process
of compilation. Metadata contains the description of the program, such as classes and interfaces, the dependencies and
the versions of the components used in the program.
3. The IL and the metadata are linked in assembly.
4. The compiler creates the .EXE or .DLL file.
5. When you execute the .EXE or .DLL file, the code (converted to IL) and all the other relevant information from the base
class library is sent to the class loader. The class loader loads the code in the memory.
6. Before the code can be executed, the .NET framework needs to convert the IL into native or CPU-specific code. The
Just-in-time (JIT) compiler translates the code from IL to managed native code. The CLR supplies a JIT compiler for
each supported CPU architecture. During the process of compilation, the JIT compiler compiles only the code that is
required during execution instead of compiling the complete IL code. When an uncompiled method is invoked during
execution, the JIT compiler converts the IL for that method into native code. This process saves the time and memory
required to convert the complete IL into native code.
7. During JIT compilation, the code is also checked for type safety. Type safety ensures that objects are always accessed
in a compatible way. Therefore, if you try to pass an 8-byte value to a method that accepts a 4-byte value as a
parameter, the CLR will detect and trap such an attempt. Type safety also ensures that objects are safely isolated from
each other and are therefore safe from any malicious corruption.
8. After translating the IL into native code, the converted code is sent to the .NET runtime manager.
9. The .NET runtime manager executes the code. While executing the code, a security check is performed to ensure that
the code has the appropriate permissions for accessing the available resources.
The language interoperability and .NET Class Framework are not possible without all the language sharing the same
data type. CTS is an important part of the runtime support for cross-language integration. The CTS performs the
following functions:
Establishes a framework that enables cross-language integration, type safety and high performance code execution.
Provides an object-oriented model that supports the complete implementation of many programming languages.
Information about program structure is language-agnostic, so that it can be referenced between languages and tools,
making it easy to work with code written in a language you are not using.
Common Language Specification (CLS)
A set of base rules to which any language targeting the CLI should conform in order to interoperate with other CLS-
compliant languages. The CLS rules define a subset of the Common Type System.
Virtual Execution System (VES)
The VES loads and executes CLI-compatible programs, using the metadata to combine separately generated pieces of
code at runtime.
The Common Language Runtime
The CLR is one of the most essential components of the .NET framework. The CLR or the runtime provides functionality
such as exception handling, security, debugging, and versioning support to any language that targets it. The CLR can
execute programs written any language. You can use the compilers to write the code that runs in the managed
execution environment provided by the CLR. The code that is developed with a language compiler that targets the CLR
is managed code. On the other hand, the code that is developed without considering the conventions and
requirements of the common language run time is called unmanaged code.
CLR activates objects, performs security checks, lays them out in memory, executes them and garbage collects these
objects as well.
The CLR is a runtime engine that loads required classes, performs just in time compilations, and enforces security
checks and a bunch of other runtime functions.
The CLR executables are either exe or DLL files that consist mostly of metadata and code. These executables must
adhere to a file format called the Portable Executable (PE) file format.
Features Provided by CLR
Some of the features provided by the CLR are as follows: -
Automatic Memory Management: The CLR provides the garbage collection feature for managing the lifetime of an
object. This process relieves a programmer of the task of manual memory management by deallocating the blocks of
memory associated with objects that are no longer being used. The objects whose lifetime is managed by the garbage
collection process are called managed data.
Standard Type System: The CLR implements a formal specification calledCommon Type System (CTS). The CTS is an
important part of the support provided by the CLR for cross-language integration because it provides a type system
that is common across all programming languages. It also defines the rules that ensure that objects written in different
languages can interact with each other.
Language Interoperability: Language interoperability is the ability of an application to interact with another application
written in a different programming language. Language interoperability helps maximize code reuse. For example, you
can write a class in Visual Basic and inherit it in a code written in Visual C++ or c#.
Platform Independence: When you compile a program developed in language that targets the CLR, the compiler
translates the code into an intermediate language. This language is CPU-independent. This means that the code can be
executed from any platform that supports the .NET CLR.
Security Management The traditional operating system security model provides permissions to access resources, such
as memory and data, based on user accounts. In .NET platform security is achieved through the Code Access Security
(CAS) model. The CAS model specifies what the code can access instead of specifying who can access resources.
Type Safety: This feature ensures that objects are always accessed in compatible ways. Therefore the CLR will prohibit
a code from assigning a 10-byte value to an object that occupies 8 bytes.
OOPS & C#
The skeleton of object – oriented programming is of course the concepts of class. The C# on OOPS explains classes
and their importance in implementation of object oriented principles.
Any language can be called object oriented if it has data and method that use data encapsulated in items named
objects. An object oriented programming method has many advantages; some of them are flexibility and code
reusability.
Key Concepts of Object Orientation
Abstraction
Encapsulation
Inheritance
Polymorphism
Abstraction is the ability to generalize an object as a data type that has a specific set of characteristics and is able to
perform a set of actions.
Object-oriented languages provide abstraction via classes. Classes define the properties and methods of an object
type.
Examples:
You can create an abstraction of a dog with characteristics, such as color, height, and weight, and actions such as run
and bite. The characteristics are called properties, and the actions are called methods.
A Recordset object is an abstract representation of a set of data.
Classes are blueprints for Object.
Objects are instance of classes.
Object References
When we work with an object we are using a reference to that object. On the other hand, when we are working with
simple data types such as Integer, we are working with the actual value rather than a reference.
When we create a new object using the New keyword, we store a reference to that object in a variable. For instance:
Draw MyDraw = new Draw;
This code creates a new instance of Draw. We gain access to this new object via the MyDraw variable. This variable
holds a reference to the object.
Now we have a second variable, which also has a reference to that same object. We can use either variable
interchangeably, since they both reference the exact same object. The thing we need to remember is that the variable
we have is not the object itself but, rather, is just a reference or pointer to the object itself.
Early binding means that our code directly interacts with the object, by directly calling its methods. Since the
compiler knows the object’s data type ahead of time, it can directly compile code to invoke the methods on the object.
Early binding also allows the IDE to use IntelliSense to aid our development efforts; it allows the compiler to ensure
that we are referencing methods that do exist and that we are providing the proper parameter values.
Late binding means that our code interacts with an object dynamically at run-time. This provides a great deal of
flexibility since our code literally doesn’t care what type of object it is interacting with as long as the object supports
the methods we want to call. Because the type of the object isn’t known by the IDE or compiler, neither IntelliSense
nor compile-time syntax checking is possible but we get unprecedented flexibility in exchange.
If we enable strict type checking by using Option Strict On at the top of our code modules, then the IDE and compiler
will enforce early binding behavior. By default, Option Strict is turned off and so we have easy access to the use of late
binding within our code.
Access Modifiers Access Modifiers are keywords used to specify the declared accessibility of a member of a type.
Public is visible to everyone. A public member can be accessed using an instance of a class, by a class’s internal code,
and by any descendants of a class.
Private is hidden and usable only by the class itself. No code using a class instance can access a private member
directly and neither can a descendant class.
Protected members are similar to private ones in that they are accessible only by the containing class. However,
protected members also may be used by a descendant class. So members that are likely to be needed by a descendant
class should be marked protected.
Internal/Friend is public to the entire application but private to any outside applications. Internal is useful when you
want to allow a class to be used by other applications but reserve special functionality for the application that contains
the class. Internal is used by C# and Friend by VB .NET.
Protected Internal may be accessed only by a descendant class that’s contained in the same application as its base
class. 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.
Composition of an OBJECT
We use an interface to get access to an object’s data and behavior. The object’s data and behaviors are contained
within the object, so a client application can treat the object like a black box accessible only through its interface. This
is a key object-oriented concept called Encapsulation. The idea is that any programs that make use of this object won’t
have direct access to the behaviors or data-but rather those programs must make use of our object’s interface.
There are three main parts of Object:
1. Interface
2. Implementation or Behavior
3. Member or Instance variables
Interface
The interface is defined as a set of methods (Sub and Function routines), properties (Property routines), events, and
fields (variables or attributes) that are declared Public in scope.
Implementation or Behavior
The code inside of a method is called the implementation. Sometimes it is also called behavior since it is this code that
actually makes the object do useful work.
Client applications can use our object even if we change the implementation-as long as we don’t change the interface.
As long as our method name and its parameter list and return data type remain unchanged, we can change the
implementation all we want.
So Method Signature depends on:
Method name
Data types of parameters
Either Parameter is passed ByVal or ByRef.
Return type of method
It is important to keep in mind that encapsulation is a syntactic tool-it allows our code to continue to run without
change. However, it is not semantic-meaning that, just because our code continues to run, doesn’t mean it continues
to do what we actually wanted it to do.
Member or Instance Variables
The third key part of an object is its data, or state. Every instance of a class is absolutely identical in terms of its
interface and its implementation-the only thing that can vary at all is the data contained within that particular object.
Member variables are those declared so that they are available to all code within our class. Typically member variables
are Private in scope-available only to the code in our class itself. They are also sometimes referred to as instance
variables or as attributes. The .NET Framework also refers to them as fields.
We shouldn’t confuse instance variables with properties. A Property is a type of method that is geared around
retrieving and setting values, while an instance variable is a variable within the class that may hold the value exposed
by a Property.
Interface looks like a class, but has no implementation.
The only thing it contains is definitions of events, indexers, methods and/or properties. The reason interfaces only
provide definitions is because they are inherited by classes and structs, which must provide an implementation for each
interface member defined.
Defining an Interface: MyInterface.cs
interface IMyInterface
{
void MethodToImplement();
}
Above listing shows defines an interface named IMyInterface.
All the methods of Interface are public by default and no access modifiers (like private, public) are allowed with any
method of Interface.
Using an Interface: InterfaceImplementer.cs
class InterfaceImplementer : IMyInterface
{
public void MethodToImplement()
{
Console.WriteLine(“MethodToImplement() called.”);
}
}
The InterfaceImplementer class in above listing implements the IMyInterface interface. Indicating that a class inherits
an interface is the same as inheriting a class. In this case, the following syntax is used:
class InterfaceImplementer : IMyInterface
Note that this class inherits the IMyInterface interface; it must implement its all members. While implementing
interface methods all those needs to be declared public only. It does this by implementing the MethodToImplement()
method. Notice that this method implementation has the exact same signature, parameters and method name, as
defined in the IMyInterface interface. Any difference will cause a compiler error.
Inheritance is the idea that one class, called a subclass, can be based on another class, called a base class.
Inheritance provides a mechanism for creating hierarchies of objects.
Inheritance is an important object-oriented concept. It allows you to build a hierarchy of related classes, and to reuse
functionality defined in existing classes.
Inheritance is the ability to apply another class’s interface and code to your own class.
Normal base classes may be instantiated themselves, or inherited. Derived classes can inherit base class members
marked with protected or greater access. The derived class is specialized to provide more functionality, in addition to
what its base class provides. Inheriting base class members in derived class is not mandatory.
C# supports two types of Inheritance mechanisms: -
1) Implementation Inheritance
2) Interface Inheritance
What is Implementation Inheritance?
- When a class (type) is derived from another class(type) such that it inherits all the members of the base type it is
Implementation Inheritance
What is Interface Inheritance?
- When a type (class or a struct) inherits only the signatures of the functions from another type it is Interface
Inheritance
In general, Classes can be derived from another class, hence support Implementation inheritance At the same time
Classes can also be derived from one or more interfaces Hence they support Interface inheritance Structs can derive
from one more interface, hence support Interface Inheritance Structs cannot be derived from another class they are
always derived from SystemValueType
Types of Inheritance
1. Single Inheritance
2. Multilevel Inheritance
3. Multiple Inheritance (Implementation is possible through Interface)
4. Hierarchical Inheritance
Multilevel Inheritance
Class B
Class B
Single Inheritance
Class A
Class D
Class C
Class A
Hierarchical Inheritance
Class A
Class B
Class C
Class A
Class B
Class C
Multiple Inheritance
Example: -
Single Inheritance: – Multilevel Inheritance: – Hierarchical Inheritance: –
Method overriding and hiding makes use of the following three method keywords –
1. new
2. virtual
3. override
1. When a derived class inherits from a base class, it gains all the methods, fields, properties and events of the base
class. To change the data and behavior of a base class, you have two choices: you can replace the base member with
a new derived member, or you can override a virtual base member.
Replacing a member of a base class with a new derived member requires the new keyword. If a base class defines a
method, field, or property, the new keyword is used to create a new definition of that method, field, or property on a
derived class. The new keyword is placed before the return type of a class member that is being replaced. For
example:
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
DerivedClass B = new DerivedClass();
B.DoWork(); // Calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // Calls the old method.
2,3. In order for an instance of a derived class to completely take over a class member from a base class, the base
class has to declare that member as virtual. This is accomplished by adding the virtual keyword before the return
type of the member. A derived class then has the option of using theoverride keyword, instead of new, to replace the
base class implementation with its own. For example:
public class BaseClass
{
public virtual void DoWork() { }
public virtual int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public override void DoWork() { }
public override int WorkProperty
{
get { return 0; }
}
}
DerivedClass B = new DerivedClass();
B.DoWork(); // Calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // Also calls the new method.
Remarks about Virtual
When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding
member in the most derived class is called, which might be the original member, if no derived class has overridden the
member.
You cannot use the virtual modifier with the static, abstract, private or override modifiers.
Virtual properties behave like abstract methods, except for the differences in declaration and invocation syntax.
It is an error to use the virtual modifier on a static property.
A virtual inherited property can be overridden in a derived class by including a property declaration that uses the
override modifier.
An override method provides a new implementation of a member inherited from a base class. The method overridden
by an override declaration is known as the overridden base method. The overridden base method must have the same
signature as the override method.
You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.
An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual
method must have the same access level modifier.
You cannot use the modifiers new, static, virtual, or abstract to modify an override method.
An overriding property declaration must specify the exact same access modifier, type, and name as the inherited
property, and the overridden property must be virtual, abstract, or override.
Class and Objects
Classes
A class is a construct that enables you to create your own custom types by grouping together variables of other types,
methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared
as static, client code can use it by creating objects or instances which are assigned to a variable. The variable remains
in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If
the class is declared as static, then only one copy exists in memory and client code can only access it through the class
itself, not an instance variable.
Declaring Class
public class Customer
{
//Fields, properties, methods and events go here…
}
The class keyword is preceded by the access level. Because public is used in this case, anyone can create objects from
this class. The name of the class follows the class keyword.
Objects
An object is basically a block of memory that has been allocated and configured according to the blueprint. A program
may create many objects of the same class. Objects are also called instances, and they can be stored in either a
named variable or in an array or collection.
Creating Objects
A class and an object are different things. A class defines a type of object, but it is not an object itself. An object is a
concrete entity based on a class, and is sometimes referred to as an instance of a class.
Objects can be created by using the new keyword followed by the name of the class that the object will be based on,
like this:
Customer object1 = new Customer();
When an instance of a class is created, a reference to the object is passed back to the programmer. In the previous
example, object1 is a reference to an object that is based on Customer.
Class Modifiers
A class-declaration can optionally include a sequence of class modifiers:
class-modifiers:
class-modifier
class-modifiers class-modifier
class-modifier:
new, public, protected, internal, private, abstract, sealed
The new modifier is permitted on nested classes. The new modifier can be used to modify a nested type if the nested
type is hiding another type.
The public, protected, internal, and private modifiers control the accessibility of the class. Depending on the
context in which the class declaration occurs, some of these modifiers may not be permitted
The abstract modifier is used to indicate that a class is incomplete and that it is intended to be used only as a base
class. An abstract class differs from a non-abstract class in the following ways:
An abstract class cannot be instantiated directly, and it is a compile-time error to use the new operator on an abstract
class. While it is possible to have variables and values whose compile-time types are abstract, such variables and
values will necessarily either be null or contain references to instances of non-abstract classes derived from the
abstract types.
An abstract class is permitted (but not required) to contain abstract methods and members.
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.
Example: -
// abstract_keyword.cs
// Abstract Classes
using System;
abstract class MyBaseC // Abstract class
{
protected int x = 100;
protected int y = 150;
public abstract void MyMethod(); // Abstract method
public abstract int GetX // Abstract property
{
get;
}
public abstract int GetY // Abstract property
{
get;
}
}
class MyDerivedC: MyBaseC
{
public override void MyMethod()
{
x++;
y++;
}
public override int GetX // overriding property
{
get
{
return x+10;
}
}
public override int GetY // overriding property
{
get
{
return y+10;
}
}
public static void Main()
{
MyDerivedC mC = new MyDerivedC();
mC.MyMethod();
Console.WriteLine(“x = {0}, y = {1}”, mC.GetX, mC.GetY);
}
}
The sealed modifier is used to prevent derivation from a class. A compile-time error occurs if a sealed class is specified
as the base class of another class.
A sealed class cannot also be an abstract class.
The sealed modifier is primarily used to prevent unintended derivation, but it also enables certain run-time
optimizations. In particular, because a sealed class is known to never have any derived classes, it is possible to
transform virtual function member invocations on sealed class instances into non-virtual invocations.
Example: use of Sealed modifier
// cs_sealed_keyword.cs
// Sealed classes
using System;
sealed class MyClass
{
public int x;
public int y;
}
class MainClass
{
public static void Main()
{
MyClass mC = new MyClass();
mC.x = 110;
mC.y = 150;
Console.WriteLine(“x = {0}, y = {1}”, mC.x, mC.y);
}
}
Output: x=110, y=150
Constructors
Whenever a class or struct is created, its constructor is called. A class or struct may have multiple constructors that
take different arguments.
Constructors allow the programmer to set default values, limit instantiation, and write code that is flexible and easy to
read.
Constructor is used to initialize an object (instance) of a class.
Constructor is a like a method without any return type.
Constructor has same name as class name.
Constructor follows the access scope (Can be private, protected, public, Internal and external).
Constructor can be overloaded.
Example: -
class Program
{
class C1
{
int a, b;
public C1(int x, int y)
{
this.a = x;
this.b = y;
}
public static C1 create_instance()
{ return new C1(12, 20); }
public void display()
{
Console.WriteLine(“Value of a: {0}”, a);
Console.WriteLine(“Value of b: {0}”, b);
int z = a + b;
Console.WriteLine(z);
}
}
static void Main(string[] args)
{ // Here the class is initiated using a static method of the
class than only you can use private constructor
C1 ob1 = C1.create_instance();
ob1.display();
Console.ReadLine();
}
}
Static Constructors
C# supports two types of constructor, a class constructor static constructor and an instance constructor (non-static
constructor).
Static constructors might be convenient, but they are slow. The runtime is not smart enough to optimize them in the
same way it can optimize inline assignments. Non-static constructors are inline and are faster.
Static constructors are used to initializing class static data members.
Point to be remembered while creating static constructor:
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.
Static members are preloaded in the memory. While instance members are post loaded into memory.
Static methods can only use static data members.
Example:
class Program
{
public class test
{
static string name;
static int age;
static test()
{
Console.WriteLine(“Using static constructor to initialize
static data members”);
name = “John Sena”;
age = 23;
}
public static void display()
{
Console.WriteLine(“Using static function”);
Console.WriteLine(name);
Console.WriteLine(age);
}
}
static void Main(string[] args)
{
test.display();
Console.ReadLine();
}}
Output:
Using static constructor to initialize static data members
Using static function
John Sena
23
Copy Constructor
If you create a new object and want to copy the values from an existing object, you use copy constructor.
This constructor takes a single argument: a reference to the object to be copied.
Example:
class Program
{
class c1
{
int a, b;
public c1(int x, int y)
{
this.a = x;
this.b = y;
}
// Copy construtor
public c1(c1 a)
{
this.a = a.a;
this.b = a.b;
}
public void display()
{
int z = a + b;
Console.WriteLine(z);
}
}
static void Main(string[] args)
{
c1 ob1 = new c1(10, 20);
ob1.display();
// Here we are using copy constructor. Copy constructor is
using the values already defined with ob1
c1 ob2 = new c1(ob1);
ob2.display();
Console.ReadLine();
}
}
Output:
30
30
Destructors
The .NET framework has an in built mechanism called Garbage Collection to de-allocate memory occupied by the un-
used objects. The destructor implements the statements to be executed during the garbage collection process. A
destructor is a function with the same name as the name of the class but starting with the character ~.
Example:
class Complex
{
public Complex()
{
// constructor
}
~Complex()
{
// Destructor
}
}
Remember that a destructor can’t have any modifiers like private, public etc. If we declare a destructor with a modifier,
the compiler will show an error.
Also destructor will come in only one form, without any arguments.
There is no parameterized destructor in C#.
Destructors are invoked automatically and can’t be invoked explicitly. An object becomes eligible for garbage collection,
when it is no longer used by the active part of the program. Execution of destructor may occur at any time after the
instance or object becomes eligible for destruction.
Operator Overloading
Operator overloading permits user-defined operator implementations to be specified for operations where one or both
of the operands are of a user-defined class or struct type.
In another way, Operator overloading is a concept in which operator can define to work with the user defined data
types such as structs and classes in the same way as the pre-defined data types.
There are many operators which can not be overloaded, which are listed below: -
Conditional Operator &&, ||
Compound Assignment +=, -=, *=, /=, %=
Other Operators [], ( ), =, ?:, ->, new, sizeof, typesof.
public class Item
{
public int i;
public Item(int j)
{ i = j; }
public static Item operator +(Item x, Item y)
{
Console.WriteLine(“OPerator +” + x.i + “” + y.i);
Item z = new Item(x.i + y.i);
return z;
}
}
class Program
{
static void Main(string[] args)
{
Item a = new Item(10);
Item b = new Item(5);
Item c;
c = a + b;
Console.WriteLine(c.i);
Console.Read();
}
}
Output: Operator + 10 5
15
In C#, a special function called operator function is used for overloading purpose.
These special function or method must be public and static.
They can take only value arguments.
The ref and out parameters are not allowed as arguments to operator functions.
interface IPoint
{
int x
{ get; set; }
int y
{ get; set; }
}
namespace Ex_Interface
{
class MyPoint:IPoint
{
private int myX;
private int myY;
public MyPoint(int x, int y)
{
myX= x;
myY=y;
}
public int x
{
get
{
return myX;
}
set
{
myX=value;
}
}
public int y
{
get
{
return myY;
}
set
{
myY=value;
}
}
}
class Program
{
private static void PrintPoint(IPoint P)
{
Console.WriteLine(“x={0}, y={1}”,P.x,P.y);
}
static void Main(string[] args)
{
MyPoint P = new MyPoint(2, 3);
Console.Write(“My Point::”);
PrintPoint(P);
Console.Read();
}
}
}
Output:
My Point::x=2, y=3
Another Example of Interface by Casting Interface methods:
interface add
{ int sum();}
interface Multiply
{ int mul();}
class Calculate : add, Multiply
{
int a, b;
public Calculate(int x, int y)
{
a = x;
b = y;
}
public int sum()
{ return (a + b);}
public int mul()
{ return a * b; }
}
namespace Ex_MultipleInterface
{
class Program
{
static void Main(string[] args)
{
Calculate cal = new Calculate(5, 10);
add A = (add)cal;
Console.WriteLine(“Sum::” + A.sum());
Multiply M = (Multiply)cal;
Console.WriteLine(“Multiplication::” + M.mul());
Console.Read();
}
}
}
Output:
Sum::15
Multiplication::50
Delegates
In .NET, you use delegates to call event procedure. Delegates are objects that you use to call the methods of other
objects. Delegates are said to be object-oriented function pointers since they allow a function to be invoked indirectly
by using a reference to the function.
However, unlike function pointers, the delegates in .NET are reference types, based on the class System.Delegate. In
addition, delegates in .NET can reference both shared and instance methods.
In another way, a delegate can be defined as a type safe function pointer. You use delegates to call the methods of
other objects. They are object-oriented function pointers since they allow a function to be invoked indirectly by using a
reference to the function.
Where are Delegates used?
The most common example of using delegates is in events.
You define a method that contains code for performing various tasks when an event (such as a mouse click) takes
place.
This method needs to be invoked by the runtime when the event occurs. Hence this method, that you defined, is
passed as a parameter to a delegate.
Starting Threads/Parallel Processing:
You defined several methods and you wish to execute them simultaneously and in parallel to whatever else
the application is doing. This can be achieved by starting new threads. To start a new thread for your method you pass
your method details to a delegate.
Generic Classes: Delegates are also used for generic class libraries which have generic functionality defined. However
the generic class may need to call certain functions defined by the end user implementing the generic class. This can
be done by passing the user defined functions to delegates.
Creating and Using Delegates:
Using delegates is a two step process-
……….1) Define the delegate to be used
……….2) Create one or more instances of the delegate
Syntax for defining a delegate:
delegate string reviewStatusofARegion();
to define a delegate we use a key word delegate followed by the method signature the delegate represents. In the
above example string reviewStatusofARegion(); represents any method that returns a string and takes no parameters.
Syntax for creating an instance of the delegate:
reviewStatusofARegion = new reviewStatusofARegion(myClass.getEurope);
private string getEurope()
{
return “Doing Great in Europe”;
}
To create an instance of the delegate you call its constructor. The delegate constructor takes one parameter which is
the method name.
The method signature should exactly match the original definition of the delegate. If it does not match the compiler
would raise an Error.
C# provides support for Delegates through the class called Delegate in the System namespace. Delegates are of two
types.
Single-cast delegates
Multi-cast delegates
A Single-cast delegate is one that can refer to a single method whereas a Multi-cast delegate can refer to and
eventually fire off multiple methods that have the same signature.
The signature of a delegate type comprises are the following.
The name of the delegate
The arguments that the delegate would accept as parameters
The return type of the delegate
A delegate is either public or internal if no specifier is included in its signature. Further, you should instantiate a
delegate prior to using the same.
The following is an example of how a delegate is declared.
Listing 1: Declaring a delegate
public delegate void TestDelegate(string message);
The return type of the delegate shown in the above example is “void” and it accepts a string argument. Note that the
keyword “delegate” identifies the above declaration as a delegate to a method. This delegate can refer to and
eventually invoke a method that can accept a string argument and has a return type of void, i.e., it does not return
any value.
Listing 2: Instantiating a delegate
TestDelegate t = new TestDelegate(Display);
Implementing Delegates in C#
This section illustrates how we can implement and use delegates in C#.This section illustrate how we can implement
and use delegates in C#.
Example 1: Single Cast Delegate
namespace Ex_Delegate
{
delegate int Operation(int x, int y); //declaration
class Metaphor
{
public static int Add(int a, int b)
{ return a + b; }
public static int Sub(int a, int b)
{ return a – b; }
public static int Mul(int a, int b)
{ return a * b; }
}
class Program
{
static void Main(string[] args)
{ // Delegate instances
Operation opr1 = new Operation(Metaphor.Add);
Operation opr2 = new Operation(Metaphor.Sub);
Operation opr3 = new Operation(Metaphor.Mul);
//invoking of delegates
int ans1 = opr1(200, 100);
int ans2 = opr2(200, 100);
int ans3 = opr3(20, 10);
Console.WriteLine(“\n Addition:” + ans1);
Console.WriteLine(“\n Subtract:” + ans2);
Console.WriteLine(“\n Multiplication:” + ans3);
Console.Read();
} }}
Example 2: Single Cast Delegate
namespace Ex_SingleCastDelegate
{ //Declare the delegate
public delegate void TestDelegate(string message);
class Program
{
public static void Display(string message)
{Console.WriteLine(“The string entered is : ” + message);}
static void Main(string[] args)
{ //Initiate the delegate
TestDelegate t = new TestDelegate(Display);
Console.WriteLine(“Please enter a string::”);
string message = Console.ReadLine();
t(message);
Console.ReadLine();
}}}
Multicast Delegate
A multi-cast delegate is basically a list of delegates or a list of methods with the same signature. A multi-cast delegate
can call a collection of methods instead of only a single method.
Example: Multicast Delegate
namespace Ex_MulticastDelegate
{
public delegate void TestDelegate();
class Program
{
public static void Display1()
{
Console.WriteLine(“This is first method”);
}
public static void Display2()
{
Console.WriteLine(“This is second method”);
}
static void Main(string[] args)
{
TestDelegate t1 = new TestDelegate(Display1);
TestDelegate t2 = new TestDelegate(Display2);
t1 = t1 + t2; // Make t1 a multi-cast delegate
t1(); //Invoke delegate
Console.Read();
}}}
In another way, You can also assign the references of multiple methods to a delegate and use it to invoke multiple
methods. Such a delegate is called a multi-cast delegate as multiple method references are cast to it and then the
delegate is used to invoke these methods.
What are Attributes?
An Attribute is a declarative tag which can be used to provide information to the compiler about the behaviour of the
C# elements such as classes and assemblies.
C# provides convenient technique that will handle tasks such as performing compile time operations , changing the
behaviour of a method at runtime or maybe even handle unmanaged code.
C# Provides many Built-in Attributes.
Some Popular ones are
Obsolete
DllImport
Conditional
WebMethod
Predefined attributes
Example:
Pre-defined attributes are used to store external information into metadata. For example, consider the following piece
of code:
public class testAttribute {
[DllImport("sampleDLL.dll")]
public static extern sampleFunction(int sampleNo, string sampleString );
public static void Main( ) {
string strVar;
sampleFunction(10, “Test Attribute”);
}
}
Using the example code above, you can import a method calledsampleFunction from sampleDLL.dll and use it in
your program as if it’s your own method. This is achieved using the pre-defined attribute “DllImport”.
Multi-Threading
Multithreading forms a subset of multitasking. Instead of having switch between programs this feature switches
between different parts of the same program. For example when you are writing words in Ms-word then spell checking
is going on background.
Thread – A thread (or “thread of execution”) is a sort of context in which code is running. Any one thread follows
program flow for wherever it is in the code, in the obvious way.
A thread is a unit of processing, and multitasking is the simultaneous execution of multiple threads. Multitasking comes
in two flavors: cooperative and preemptive. Very early versions of Microsoft Windows supported cooperative
multitasking, which meant that each thread was responsible for relinquishing control to the processor so that it could
process other threads.
However, Microsoft Windows NT-and, later, Windows 95, Windows 98, and Windows 2000-support the same
preemptive multitasking that OS/2 does. With preemptive multitasking, the processor is responsible for giving each
thread a certain amount of time in which to execute-a timeslice. The processor then switches among the different
threads, giving each its timeslice, and the programmer doesn’t have to worry about how and when to relinquish control
so that other threads can run. .NET will only work only on preemptive multitasking operating systems.
1. Starting Thread
Object thread is obtained from System.Threading namespace. With the use object of this class we can create a new
thread, delete, pause, and resume threads. Simple a new thread is created by Thread class and started
byThread.Start().
eg. Thread th = new Thread (new ThreadStart (somedata));
th.Start();
2. Pausing Thread
Some time the requirement to pause a thread for certain time of interval; you can attain the same by using Sleep (n)
method. This method takes an integer value to determine how long a thread should pause or Sleep.
eg. th.Sleep(2000);
Note:
To pause or sleep a thread for an in determine time, just call the sleep () method as: [make sure you have added
System.Threading namespace]Thread.Sleep(TimeOut.Infinite).
To Resume or interrupt this call : Thread.Interrupt () method.
3. Suspending Thread
Of course, there is a Suspend () method which suspends the thread. It is suspended until a Resume () method called.
eg. if (th.ThreadState = = ThreadState.Running)
th.Suspended();
4. Resuming Thread
To Resume a suspended thread, there is a Resume () method, thread resumes if earlier suspended if not so then there
is no effect of Resume () method on the thread.
eg. if (th.ThreadState = = ThreadState.Suspended)
th.Resume();
5. Killing Thread
You can call Abort () method to kill a thread, before calling the same method, make sure thread is alive.
eg. if (th.IsAlive)
th.Abort();
Suspend and Resume in Threading
It is similar to sleep and Interrupt. Suspend allows you to block a thread until another thread calls Thread.Resume
().The difference between sleep and suspend is that the later does no immediately place a thread in the wait state. The
thread does not suspend until the .Net runtime determines that it is in a safe place to suspend it. Sleep will
immediately place a thread in a wait state.
Important:
You can change thread priority for that just supply : th.Priority = ThreadPriority.Highest. [th – Thread name]. Priority
sets the sequence of thread in which they are running. You can set the following priority to thread(s):
1. ThreadPriority.Highest
2. ThreadPriority.AboveNormal
3. ThreadPriority.Normal
4. ThreadPriority.BelowNormal
5. ThreadPriority.Lowest
Code Example of Multithreading
using System.Threading;
namespace Ex_ThreadExample
{
class SimpleThread
{
private Thread thread1;
private Thread thread2;
private void Method1()
{
for (int i =0; i<10;i++)
{
Console.WriteLine (“i = ” +i);
Thread.Sleep (400); // 200 miliseconds pause
}
}
private void Method2()
{
for (int i =0;i<10;i++)
{
Console.WriteLine (“i = ” + 100 * i);
Thread.Sleep (100); // 100 miliseconds pause
}
}
static void Main(string[] args)
{
SimpleThread app = new SimpleThread ();
app.thread1 = new Thread (new ThreadStart (app.Method1)); // thread start Delegate Method
app.thread2 = new Thread (new ThreadStart (app.Method2));
app.thread1.Start ();
app.thread2.Start ();
Console.WriteLine ();
Console.ReadLine();
}
}
}
————-x————–x————–x—————x———-
Socket Programming in C#
Network programming in windows is possible with sockets. A socket is like a handle to a file. Socket programming
resembles the file IO as does the Serial Communication. You can use sockets programming to have two applications
communicate with each other. The application are typically on the different computers but they can be on same
computer. For the two applications to talk to each either on the same or different computers using sockets one
application is generally a server that keeps listening to the incoming requests and the other application acts as a client
and makes the connection to the server application.
The server application can either accept or reject the connection. If the server accepts the connection, a dialog can
begin with between the client and the server. Once the client is done with whatever it needs to do it can close the
connection with the server. Connections are expensive in the sense that servers allow finite connections to occur.
During the time client has an active connection it can send the data to the server and/or receive the data.
Socket programming in .NET is made possible by Socket class present inside the System.Net. Sockets namespace.
Socket class has several method and properties and a constructor.
The first step is to create an object of this class. Since there is only one constructor we have no choice but to use it.
Once we have created a Socket we need to make a connection to the server since we are using connection-based
communication.
To connect to the remote computer we need to know the IP Address and port at which to connect.
In .NET there is a class under System.Net namespace called IPEndPoint which represents a network computer as an IP
address and a port number.
The IPEndPoint has two constructors – one that takes a IP Address and Port number and one that takes long and port
number. Since we have computer IP address we would use the former
public IPEndPoint(System.Net.IPAddress address, int port);
As you can see the first parameter takes a IPAddress object. If you examine the IPAddress class you will see that it has
a static method called Parse that returns IPAddress given a string ( of dot notation ) and second parameter will be the
port number. Once we have endpoint ready we can use Connect method of Socket class to connect to the end point (
remote server computer ).
Client Code:
using System;
using System.Net.Sockets;
public class Client
{
static public void Main( string[] Args )
{
TCPClient socketForServer;
try
{
socketForServer = new TCPClient(“localHost”, 10);
}
catch
{
Console.WriteLine(
“Failed to connect to server at {0}:999″, “localhost”);
return;
}
NetworkStream networkStream = socketForServer.GetStream();
System.IO.StreamReader streamReader = newSystem.IO.StreamReader(networkStream);
System.IO.StreamWriter streamWriter = newSystem.IO.StreamWriter(networkStream);
try
{
string outputString;
// read the data from the host and display it
{
outputString = streamReader.ReadLine();
Console.WriteLine(outputString);
streamWriter.WriteLine(“Client Message”);
Console.WriteLine(“Client Message”);
streamWriter.Flush();
}
}
catch
{
Console.WriteLine(“Exception reading from Server”);
}
// tidy up
networkStream.Close();
}
}
———–x—————-x————————–x————————-x—————-x—————x———-
Error Handling
Overview of Exception Handling
Exceptions are error conditions that arise when the normal flow of a code path-that is, a series of method calls on the
call stack-is impractical. Exception handling is an in built mechanism in .NET framework to detect and handle run time
errors. The exceptions are anomalies that occur during the execution of a program. They can be because of user, logic
or system errors. If a user (programmer) do not provide a mechanism to handle these anomalies, the .NET run time
environment provide a default mechanism, which terminates the program execution. C# provides three keywords try,
catch and finally to do exception handling. The try encloses the statements that might throw an exception whereas
catch handles an exception if one exists. The finally can be used for doing any clean up process.
The general form try-catch-finally in C# is shown below:
try
{
// Statement which can cause an exception.
}
catch(Type x)
{
// Statements for handling the exception
}
finally
{
//Any cleanup code
}
If any exception occurs inside the try block, the control transfers to the appropriate catch block and later to the finally
block.
But in C#, both catch and finally blocks are optional. The try block can exist either with one or more catch blocks or a
finally block or with both catch and finally blocks.
If there is no exception occurred inside the try block, the control directly transfers to finally block. We can say that the
statements inside the finally block is executed always. Note that it is an error to transfer control out of a finally block
by using break, continue, return or goto.
In C#, exceptions are nothing but objects of the type Exception. The Exception is the ultimate base class for any
exceptions in C#. The C# itself provides couple of standard exceptions. Or even the user can create their own
exception classes, provided that this should inherit from either Exception class or one of the standard derived classes
of Exception class like DivideByZeroExcpetion ot ArgumentException etc.
The modified form of the above program with exception handling mechanism is as follows: -
//C#: Exception Handling
using System;
class MyClient
{
public static void Main()
{
int x = 0; int div = 0;
try
{ div = 100/x;
Console.WriteLine(“Not executed line”);
}
catch(DivideByZeroException de)
{ Console.WriteLine(“Exception occured”); }
finally
{ Console.WriteLine(“Finally Block”); }
Console.WriteLine(“Result is {0}”,div);
}
}
Multiple Catch Blocks
A try block can throw multiple exceptions, which can handle by using multiple catch blocks. Remember that more
specialized catch block should come before a generalized one. Otherwise the compiler will show a compilation error.
//C#: Exception Handling: Multiple catch
using System;
class MyClient
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100/x;
Console.WriteLine(“Not executed line”);
}
catch(DivideByZeroException de)
{ Console.WriteLine(“DivideByZeroException” ); }
catch(Exception ee)
{ Console.WriteLine(“Exception” ); }
finally
{ Console.WriteLine(“Finally Block”); }
Console.WriteLine(“Result is {0}”,div);
}
}
Catching All Exception
By providing a catch block without a brackets or arguments, we can catch all exceptions occurred inside a try block.
Even we can use a catch block with an Exception type parameter to catch all exceptions happened inside the try block
since in C#, all exceptions are directly or indirectly inherited from the Exception class.
//C#: Exception Handling: Handling all exceptions
using System;
class MyClient
{
public static void Main()
{
int x = 0;
int div = 0;
try
{ div = 100/x;
Console.WriteLine(“Not executed line”);
}
catch
{ Console.WriteLine(“oException” );}
Console.WriteLine(“Result is {0}”,div);
}
}
The following program handles all exception with Exception object.
//C#: Exception Handling: Handling all exceptions
using System;
class MyClient
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100/x;
Console.WriteLine(“Not executed line”);
}
catch(Exception e)
{ Console.WriteLine(“oException” );}
Console.WriteLine(“Result is {0}”,div);
}
}
Throwing an Exception
In C#, it is possible to throw an exception programmatically. The ‘throw’ keyword is used for this purpose. The general
form of throwing an exception is as follows.
throw exception_obj;
For example the following statement throws an ArgumentException explicitly.
throw new ArgumentException(“Exception”);
Example
//C#: Exception Handling:
using System;
class MyClient
{
public static void Main()
{
try
{ throw new DivideByZeroException(“Invalid Division”);}
catch(DivideByZeroException e)
{ Console.WriteLine(“Exception” ); }
Console.WriteLine(“LAST STATEMENT”);
}
}
Standard Exceptions
There are two types of exceptions: exceptions generated by an executing program and exceptions generated by the
common language runtime. System.Exception is the base class for all exceptions in C#. Several exception classes
inherit from this class including ApplicationException and SystemException. These two classes form the basis for most
other runtime exceptions. Other exceptions that derive directly from System.Exception include IOException,
WebException etc.
The common language runtime throws SystemException. The ApplicationException is thrown by a user program rather
than the runtime. The SystemException includes the ExecutionEngineException, StaclOverFlowException etc. It is not
recommended that we catch SystemExceptions nor is it good programming practice to throw SystemExceptions in our
applications.
System.OutOfMemoryException
System.NullReferenceException
Syste.InvalidCastException
Syste.ArrayTypeMismatchException
System.IndexOutOfRangeException
System.ArithmeticException
System.DevideByZeroException
System.OverFlowException
User-Defined Exceptions
In C#, it is possible to create our own exception class. But Exception must be the ultimate base class for all exceptions
in C#. So the user-defined exception classes must inherit from either Exception class or one of its standard derived
classes.
//C#: Exception Handling: User defined exceptions
using System;
class MyException : Exception
{
public MyException(string str)
{
Console.WriteLine(“User defined exception”);}
}
class MyClient
{
public static void Main()
{
try
{ throw new MyException(“RAJESH”); }
catch(Exception e)
{Console.WriteLine(“Exception caught here” + e.ToString()); }
Console.WriteLine(“LAST STATEMENT”);
}
}
——————x————————-x——————————x————————-x———————–
File Handling in C#
File handling is an unmanaged resource in your application system. It is outside your application domain (unmanaged
resource). It is not managed by CLR.
Data is stored in two ways, persistent and non-persistent manner.
When you open a file for reading or writing, it becomes stream.
Stream: Stream is a sequence of bytes traveling from a source to a destination over a communication path.
The two basic streams are input and output streams. Input stream is used to read and output stream is used to write.
The System.IO namespace includes various classes for file handling.
The parent class of file processing is stream. Stream is an abstract class, which is used as the parent of the classes
that actually implement the necessary operations.
The primary support of a file as an object is provided by a .NET Framework class called File. This static class is
equipped with various types of (static) methods to create, save, open, copy, move, delete, or check the existence of a
file.
Object
System.IO
System
MarshalByref
Object
System.IO
FileSystemInfo
System.IO
FileInfo
Directoryinfo
File
Path
Directory
DriveInfo
StreamWriter Class
The StreamWriter class in inherited from the abstract class TextWriter. The TextWriter class represents a writer, which
can write a series of characters.
The following table describes some of the methods used by StreamWriter class: -
Methods Description
Close the current StreamWriter object and underlying
Close
stream
Clears all buffers for the current writer and causes any
Flush
buffered data to be written to the underlying stream.
Write Writes to the Stream
Writes data specified by the overloaded parameters,
WriteLine
followed by end of line.
To cater these requirements, various standards such as XML, SOAP and Web Services Description Language (WSDL)
are used.
XML
A client passes arguments to a method exposed by a Web service. The method performs some action on the
arguments and returns the results to the client application. The data returned by the Web service can be used by the
client application, regardless of the hardware and software platform used to develop the application. To enable this
kind of data interchange, you require a standard data representation format that can be understood by any platform.
Since XML is a plain-text format that can be understood by any kind of device.
SOAP
To be able to communicate with each other, a Web service and a client application must agree upon a common
protocol. SOAP is a standard communication protocol for interchanging information in a structured format in a
distributed environment. The information exchanged between the client application and the web service is called a
message. When a client application makes a request for a web method, a SOAP packet is created. This packet contains
the name of the Web method to be invoked and the parameters to be passed to the Web method in an XML format.
This information is used to invoke the Web method with the appropriate parameters. When the SOAP packet arrives at
the Web server on which the Web service resides, the Web method name and its parameters are extracted from the
SOAP packet and the appropriate Web method is invoked.
WSDL
To be able to use a Web service, the developers of a client application need to know the methods exposed by the Web
service and the parameters to be passed to these methods. Therefore, you need a standard method to describe the
methods that are exposed by Web service. This information should be readily accessible to the Web service clients
during the design phase. This is achieved by using an XML vocabulary called Web Service Description Language
(WSDL). WSDL is a markup language that describes a Web service.
A WSDL document contains the following information: -
The web services available for a given Web site.
The purpose for which these services can be used.
The types of parameters that need to passed to a Web service.
The type of value that is returned by a Web service.
The format used to access these Web services.
The URL at which a Web service can be accessed.
Communication through
SOAP messages
Relation between Enabling Web Service Technologies
XML (eXtensible Markup Language)
XML is a text based markup language that enables you to store data in a structured format by using meaningful tags.
The term “eXtensible” implies that you can extend your ability to describe a document by defining meaningful tags for
your application.
XML is a cross-platform, hardware and software independent markup language. XML allows computers to store data in
a format that can be interpreted by any other computer system and therefore. XML can be used to transfer structured
data between heterogeneous systems. XML is used as a common data interchange format in a number of applications.
Advantages of XML
Some of the advantages offered by XML are as follows:
It provides a way of creating domain-specific vocabulary.
It allows data interchange between different computer systems.
It enables smart searches.
It provides user-selected view of data.
It allows granular updates.
An XML document usually begins with the XML declaration statement also called the Processing Instruction (PI). The PI
provides information regarding the way in which the XML file should be processed. The PI statement can be written as:
<? Xml version=”1.0” encoding “UTF-8”?>
The PI is optional. The PI uses the encoding property to specify the information about the encoding scheme that is
used to create the XML file. The encoding scheme is the standard character set for a language. UTF-8 is the standard
character set that is used to create pages written in English. This character set uses eight bits of information to
represent each character.
Therefore, UTF-8 stands for an 8-bit character set.
Tag
Tags are used to specify a name for a given piece of information. It is a means of identifying data. Data is marked-up
using tags. A tag consists of an opening and a closing angular bracket (<>). These brackets enclose the name of the
tag. Tags usually occur in pairs.
<P> Nick Peter </P>
In this example, <p> is a predefined HTML tag or mark-up. As XML allows you to create your own tags, the same
information can be stored in the following way:
<EMP_NAME> Nick Peter</EMP_NAME>
In this example, <EMP_NAME> is a new tag created using XML.
Elements
Elements are the basic units that are used to identify and describe data in XML. They are the building blocks of an XML
document. Elements are represented using tags.
XML allows you to provide meaningful names to elements, which helps improve the readability of the code. For
example: -
<Authorname> Vivek </Authorname>
In the example, the Authorname element is used to store the names of authors. In this case, the element name
provides a description of the content within the tags.
An XML document must always have a root element. A root element contains all other elements in the document.
Content
The information that is represented by the elements of an XML document is referred to as the content of that element.
For example,
<BOOKNAME> the painted Hose</BOOKNAME>
The name of the book The Painted House is the content of the BOOKNAME element. XML enables to declare and use
elements that can contain different kinds of information. An element can contain any of the following types of content:
Character or data content
Element content
Combination or mixed content
Examples
Character content
<BOOKNAME> the painted Hose</BOOKNAME>
Element content
<Author>
<Fname> John </Fname>
<Lname> Smith </Lname>
</Author>
Mixed Content
<PRODUCTDESCRIPTION>
The product is available inn four colors.
<COLOR> RED </COLOR>
<COLOR> BLUE </COLOR>
<COLOR> GREEN </COLOR>
<COLOR> YELLOW </COLOR>
</PRODUCTDESCRIPTION>
Attributes
Attributes provide additional information about the elements for which they are declared. An attribute consists of a
name-value pair. Consider the following example: -
<PRODUCTNAME PROID=”P001”> DOLL</PRODUCTNAME>
In this example, the element PRODUCTNAME has an attribute called PROID. The value of this attribute is set to 001.
Elements can have one or more attributes. Attributes or attribute values can be either mandatory or optional.
In general, an element is used to represent a definable unit. An attribute is used to represent data that further qualifies
the element. For example, an element called font could have an attribute called color that is used to specify the color of
the font.
Entity
An entity can be described as a shortcut to a set of information. It is name that is associated with a block of data. This
data can be a chunk of text or a reference to an external file that contains textual or binary information.
<DISPLAY> The price of the this toy is < 20 <DISPLAY>
In the example, < internal entity is used to display a less than (”<”) symbol.
Comment
Comments are statements that are used to explain the code. They are also used to provide documentation information
about an XML file or even the application to which the file belongs. When the code is executed, comment entries are
ignored by the parser.
Comments are created using an opening angular bracket followed by an exclamation mark and two hyphens (<!–).
This is followed by the text that comprises the comments. The comment entry can be closed using two hyphens
followed by a closing angular bracket (–>).
Example: – <! — Productdata is the root element –>
Rules for Creating Well-formed XML document
Every start tag must have an end tag.
Empty tags must be closed using a forward slash (/).
All attribute values must be given in double quotation marks.
Tags must nest correctly.
XML tags are case-sensitive. They must match each other in every implementation.
Content-type or content-model specifies whether the element contains textual data or other element.
An element can be empty, unrestricted, or a container element. The following table describes each type of
element:
Element Type Description
Empty elements have no content and are marked up as
Empty
<empty-element/>
The opposite of an empty element is an unrestricted
Unrestricted element, which can contain any element declared elsewhere
in the DTD.
Container Elements can contain character data and other elements
In addition to specifying the value type of an attribute, you also need to specify whether the attribute is optional or
mandatory. Look at the following table for attribute types: -
Attribute Type Description
If the attributes of an element is specified as #REQUIRED,
REQUIRED then the value for that attribute must be specified each time
the element is used in the XML document.
If the attribute of an element is specified as #FIXED, then
FIXED the value of the attribute can not be changed in XML
document.
IMPLIED If the attribute of an element is specified as #IMPLIED, then
the attribute is optional. An IMPLIED attribute can take text
strings as their values.
param
The param tag is used to describe the parameters of the method. Parameter tags are automatically inserted into the
header template if parameters are in the syntax. The name of the parameter is automatically inserted into the
parameter tag. The parameter description should be brief.
<param name=”…”>…</param>
/// <param name=”_value”>
/// Used to demonstrate the usage of <c>param</c>
/// </param>
see
Assigns a hyperlink to the specified text.
<see href|cref|langword=”…”/> or <see href=”…”>…</see>
/// See <see cref=”T:System.Enum”>enumeration</see
/// See <see cref=”M:TutorialXmlDocumentationTags.code”>code</see
/// See <see href=”http://www.microsoft.com”>Microsoft</see>
///<see langword=”null”/>
seealso
Adds a link to the “See Also” section.
<seealso href|cref=”…”/> or <seealso href=”…”>…</seealso>
/// <seealso cref=”T:TutorialXmlDocumentationTags”/>
/// <seealso href=”http://microsoft.com”/>
/// <seealso href=”http://www.codeplex.com/Sandcastle”>Sandcastle on CodePlex</seealso>
Unsafe Mode
When you use the new keyword to create a new instance of a reference type, you are asking the CLR to set aside
enough memory to use for the variable. The CLR allocates enough memory for the variable and associates the memory
with your variable. Under normal conditions, your code is unaware of the actual location of that memory, as far as a
memory address is concerned. After the new operation succeeds, your code is free to use the allocated memory
without knowing or caring where the memory is actually located on your system.
Occasionally, however, you need to work with a specific memory address in your C# code. Your code may need that
extra ounce of performance, or your C# code may need to work with legacy code that requires that you provide the
address of a specific piece of memory. The C# language supports a special mode, called unsafe mode, which enables
you to work directly with memory from within your C# code.
This special C# construct is called unsafe mode because your code is no longer safe from the memory-management
protection offered by the CLR. In unsafe mode, your C# code is allowed to access memory directly, and it can suffer
from the same class of memory-related bugs found in C and C++ code if you’re not extremely careful with the way you
manage memory.
Generally, When we write any program in C#, we create managed code. Managed code is executed under the control
of CLR. CLR causes that programmer do not need to manage memory and take care about memory’s allocation and
deallocation. CLR also allows you to write what is called‘unsafe code’.
The CLR knows how to manipulate three kinds of pointers:
Managed pointers: These pointers can point to data contained in the object heap managed by the garbage collector.
These pointers are not used explicitly by the C# code. They are thus used implicitly by the C# compiler when it
compiles methods with out and ref arguments.
Unmanaged function pointers: The pointers are conceptually close to the notion of delegate.
Unmanaged pointers: These pointers can point to any data contained in the user addressing space of the process. The
C# language allows to use this type of pointers in zones of code considered unsafe.
Disadvantages of UNSAFE in C#
Complex syntax, to use pointers you need to go through more complex syntax than we used to experience in C#.
Harder to use, you need be more careful and logical while using pointers, miss-using pointers might lead to the
following: -
- Overwrite other variables
- Stack Overflow
- Access areas of memory that doesn’t contain any data as they do.
- Overwrite some information of the code for the .net runtime, which will suerly lead your application to crash.
Your code will be harder to debug. A simple mistake in using pointers might lead your application to crash randomly
and unpredictably.
Type-safety, using pointers will cause the code to fail in the .net type-safety checks, and of course if your security
police don’t allow non type-safety code, then the .net framework will refuse to execute your application.
Distributed Application in C#
Introduction
Distributed computing is an integral part of almost every software development. Before .Net Remoting, DCOM was the
most used method of developing distributed application on Microsoft platform. Because of object oriented architecture,
.NET Remoting replaces DCOM as .Net framework replaces COM.
Remoting is a framework built into Common Language Runtime (CLR) in order to provide developers classes to build
distributed applications and wide range of network services. Remoting provides various features such as Object
Passing, Proxy Objects, Activation, Stateless and Stateful Object, Lease Based LifeTime and Hosting of Objects in IIS.
Benefits of Distributed Application Development:
Fault Tolerance: Fault tolerance means that a system should be resilient when failures within the system occur.
Scalability: Scalability is the ability of a system to handle increased load with only an incremental change in
performance.
Administration: Managing the system from one place.
In brief, .NET remoting is an architecture which enables communication between different application domains or
processes using different transportation protocols, serialization formats, object lifetime schemes, and modes of object
creation. Remote means any object which executes outside the application domain. The two processes can exist on the
same computer or on two computers connected by a LAN or the Internet. This is called marshalling (This is the process
of passing parameters from one context to another.), and there are two basic ways to marshal an object:
Marshal by value: the server creates a copy of the object passes the copy to the client.
Marshal by reference: the client creates a proxy for the object and then uses the proxy to access the object.
Comparison between .NET Remoting and Web services:
S.No ASP.NET WebService .NET Remoting
1 Easy to develop and deploy Involves complex programming
2 Gives extensibility by allowing us Highly extensible by allowing us to
to intercept the SOAP messages customize the different components
during the serialization and of the .NET remoting framework.
deserialization stages.
3 Accessed only over HTTP Can be accessed over any of the
protocol like HTTP, SMPT, TCP etc.
4 Webservices support only the By Using binary communication,
data types defined in the XSD .NET Remoting can provide support
type system, their by limiting the for rich type system
number of objects that can be
serialized.
Architecture:
Remote objects are accessed through channels. Channels are Transport protocols for passing the messages between
Remote objects. A channel is an object that makes communication between a client and a remote object, across app
domain boundaries. The .NET Framework implements two default channel classes, as follows:
HttpChannel: Implements a channel that uses the HTTP protocol.
TcpChannel: Implements a channel that uses the TCP protocol (Transmission Control Protocol).
Channel take stream of data and creates package for a transport protocol and sends to other machine. A simple
architecture of .NET remoting is as in below Figure.
Server Object
Remoting System
Client Object
Remoting
System
Proxy
Server Application Domain
Client Application Domain
Channel
Figure shows, Remoting system creates a proxy for the server object and a reference to the proxy will be returned to
the client. When client calls a method, Remoting system sends request thro the channel to the server. Then client
receives the response sent by the server process thro the proxy.
Example:
Let us see a simple example which demonstrates .Net Remoting. In This example the Remoting object will send us the
maximum of the two integer numbers sent.
Creating Remote Server and the Service classes on Machine 1:
Please note for Remoting support your service (Remote object) should be derived from MarshalByRefObject.
using System;
using System.Runtime.Remoting.Channels; //To support and handle Channel and channel sinks
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Http; //For HTTP channel
using System.IO;
namespace ServerApp
{
public class RemotingServer
{
public RemotingServer()
{
//
// TODO: Add constructor logic here
//
}
}
//Service class
public class Service: MarshalByRefObject
{
public void WriteMessage (int num1,int num2)
{
Console.WriteLine (Math.Max(num1,num2));
}
}
//Server Class
public class Server
{
public static void Main ()
{
HttpChannel channel = new HttpChannel(8001); //Create a new channel
ChannelServices.RegisterChannel (channel); //Register channel
RemotingConfiguration.RegisterWellKnownServiceType(typeof Service),”Service”,WellKnownObjectMode.Singleton);
Console.WriteLine (“Server ON at port number:8001″);
Console.WriteLine (“Please press enter to stop the server.”);
Console.ReadLine ();
}
}
}
Save the above file as ServerApp.cs. Create an executable by using VisualStudio.Net command prompt by,
csc /r:system.runtime.remoting.dll /r:system.dll ServerApp.cs
A ServerApp.Exe will be generated in the Class folder.
Run the ServerApp.Exe will give below message on the console
Server ON at port number:8001
Please press enter to stop the server.
In order to check whether the HTTP channel is binded to the port, type
http://localhost:8001/Service?WSDL in the browser.
You should see a XML file describing the Service class.
Please note before running above URL on the browser your server (ServerApp.Exe should be running) should be ON.
Creating Proxy and the Client application on Machine 2
SoapSuds.exe is a utility which can be used for creating a proxy dll.
Type below command on Visual studio.Net command prompt.
soapsuds -url:http://< Machine Name where service is running>:8001/Service?WSDL -oa:Server.dll
This will generates a proxy dll by name Server.dll. This will be used to access remote object.
Client Code:
using System;
using System.Runtime.Remoting.Channels; //To support and handle Channel and channel sinks
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Http; //For HTTP channel
using System.IO;
using ServerApp;
namespace RemotingApp
{
public class ClientApp
{
public ClientApp()
{
}
public static void Main (string[] args)
{
HttpChannel channel = new HttpChannel (8002); //Create a new channel
ChannelServices.RegisterChannel (channel); //Register the channel
//Create Service class object
Service svc = (Service) Activator.GetObject (typeof (Service),”http://<Machine name where Service
running>:8001/Service”); //Localhost can be replaced by
//Pass Message
svc.WriteMessage (10,20);
}
}
}
Save the above file as ClientApp.cs. Create an executable by using VisualStudio.Net command prompt by,
csc /r:system.runtime.remoting.dll /r:system.dll ClientrApp.cs
A ClientApp.Exe will be generated in the Class folder. Run ClientApp.Exe , we can see the result on
Running ServerApp.EXE command prompt.
In the same way we can implement it for TCP channel also.
ADO.NET
ADO.NET is a model used by .NET applications to communicate with a database for retrieving, accessing and updating
data.
Features of ADO.NET
Some of the features of ADO.NET are given below:
1. Disconnected data architecture – ADO.NET uses the disconnected data architecture. Applications connect to the
database only while retrieving and updating data. After data is retrieved, the connection with the databse is closed.
When the database needs to be updated, the connection is re-established. Working with applications that do not follow
a disconnected architecure leads to a wastage of valuable system resources, since the application connects to the
database and keeps the connection open until it stops running, but does not actually interact with the database except
while retrieving and updating data.
2. Data Cahed in datasets – A dataset is the most common method of accessing data since it implements a disconnected
architecture. SinceADO.NET is based on a disconnected data structure, it is not possible for the application to interact
with the database for processing each record. Therefore, the data is retrieved and store in datasets. A dataset is a
chached set of database records.You can work with the records stored in a dataset as you work with real data; the only
difference being that the dataset is independent of data source and you remain disconnected from the data source.
3. Data transfer in XML format – XML is the fundamental format for data transfer in ADO.NET. Data is transferred from a
databse into a dataset and from the dataset to another component by using XML. You can use XML file as a data
source and store data from it in a dataset. Using XML as the data transfer language is beneficial as XML is an industry
standard for exchanging information between types of applications.
4. Interaction with the database is done through data commands – All operations on the database are performed by using
data commands. A data command can be a SQL statement or a stored procedure. You can retrieve, insert, delete or
modify data from a database by executing data commands.
Data Provider
The Data Provider is responsible for providing and maintaining the connection to the database. A DataProvider is a set
of related components that work together to provide data in an efficient and performance driven manner.
The .NET Framework currently comes with two DataProviders: the SQL Data Provider which is designed only to work
with Microsoft’s SQL Server 7.0 or later and the OleDb DataProvider which allows us to connect to other types of
databases like Access and Oracle. Each DataProvider consists of the following component classes:
The Connection object which provides a connection to the database
The Command object which is used to execute a command
The DataReader object which provides a forward-only, read only, connected recordset
The DataAdapter object which populates a disconnected DataSet with data and performs update
When the Update method is called, changes in the DataSet are copied back to the database and the appropriate
InsertCommand, DeleteCommand, or UpdateCommand is executed.
ADO.NET Archtecture
The following diagram illustrates the relationship between a .NET Framework data provider and a DataSet
Heap & Stack
Introduction This video explains the concept of boxing
What goes inside when you declare a variable? and unboxing and it also shows the
Stack and Heap performance implications caused by the
same.
Value types and reference types
So which data types are ref type and value type?
Boxing and Unboxing
Performance implication of Boxing and unboxing
Source code
Introduction
This article will explain 6 important concepts Stack , heap , value types , reference types , boxing and unboxing. This
article starts first explaining what happens internally when you declare a variable and then it moves ahead to explain 2
important concepts stack and heap. Article then talks about reference types and value types and clarifies some of the
important fundamentals around them.
Finally the article concludes by demonstrating how performance is hampered due to boxing and unboxing with a
sample code.
Watch my 500 videos on various topics like design patterns,WCF, WWF , WPF, LINQ ,Silverlight,UML, Sharepoint
,Azure,VSTS and lot more click here, you can also catch me on my trainings @ click here.
When you declare a variable in a .Net application, it allocates some chunk of memory in to the RAM. This memory has
3 things first the name of the variable, second data type of the variable and finally the value of the variable.
That was a simple explanation of what happens in the memory, but depending on what kind of data type your variable
is allocated on that type of memory. There are two types of memory allocation stack memory and heap memory. In
the coming sections we will try to understand these two types of memory in more details.
In order to understand stack and heap, let’s understand what actually happens in the below code internally.
Collapse
public void Method1()
{
// Line 1
int i=4;
// Line 2
int y=2;
//Line 3
class1 cls1 = new class1();
}
It’s a 3 line code so let’s understand line by line how things execute internally.
Line 1:- When this line is executed compiler allocates a small amount of memory in to memory type called as stack.
Stack is responsible of keeping track of running memory needed in your application.
Line 2:- Now the execution moves to the next step. As the name says stack it stacks this memory allocation on the
top of the first memory allocation. You can think about stack as series of compartment or boxes put on top of each
other.
Memory allocation and de-allocation is done using LIFO (Last in first out) logic. In other words memory is allocated and
de-allocated at only one end of the memory i.e. top of the stack.
Line 3:- In line 3 we have a created an object. When this line is executed it creates a pointer on the stack and the
actual object is stored in a different type of memory location called as ‘Heap’. ‘Heap’ does not track running memory
it’s just pile of objects which can reached at any moment of time. Heap is used for dynamic memory allocation.
One more important point to note here is reference pointers are allocated on stack. The statement, Class1 cls1; does
not allocate memory for an instance of Class1, it only allocates a stack variable cls1 (and sets it to null). The time it
hits the new keyword it allocates on “HEAP”.
Exiting the method (The fun):- Now finally the execution control starts exiting the method. When it passes the end
control it clears all the memory variables which are assigned on stack. In other words all variables which are related to
‘int’ data type are de-allocated in ‘LIFO’ fashion from the stack.
The BIG catch – It did not de-allocate the heap memory. This memory will be later de-allocated by “GARBAGE
COLLECTOR”.
Now many of our developer friends must be wondering why two types of memory, can’t we just allocate everything on
just one memory type and we are done.
If you look closely primitive data types are not complex, they hold single values like ‘int i = 0’. Object data types are
complex, they reference other objects or other primitive data types. In other words they hold reference to other
multiple values and each one of them must be stored in memory. Object types need dynamic memory while primitive
needs static type memory. If the requirement is of dynamic memory it’s allocated on a heap or else it goes on a stack.
Image taken from http://michaelbungartz.wordpress.com/
Value types and reference types
Now that we have understood the concept of ‘Stack’ and ‘Heap’ it’s time to understand the concept of value types and
reference types.
Value types are types which hold both data and the memory on the same location. While a reference type has a pointer
which points to the memory location.
Below is a simple integer data type with name ‘i’ whose value is assigned to an other integer data type with name ‘j’.
Both these memory values are allocated on the stack.
When we assign the ‘int’ value to the other ‘int’ value it creates a complete different copy. In other word if you change
either of them the other does not change. These kinds of data types are called as ‘Value types’.
When we create an object and when we assign one object to the other object, they both point to the same memory
location as show in the below code snippet. So when we assign ‘obj’ to ‘obj1’ they both point to the same memory
location.
In other words if we change one of them the other object is also affected this is termed as ‘Reference types’.
In .NET depending on data types the variable is either assigned on the stack or on the heap. ‘String’ and ‘Objects’ are
reference types and any other .NET primitive data types are assigned on the stack. Below figure explains the same in a
more detail manner.
Boxing and Unboxing
WOW, you have given so much knowledge, so what’s the use of it in actual programming. One of the biggest
implications is to understand the performance hit which is incurred due to data moving from stack to heap and vice
versa.
Consider the below code snippet. When we move a value type to reference type the data is moved from the stack to
the heap. When we move reference type to a value type the data is moved from the heap to the stack.
This movement of data from the heap to stack and vice-versa creates a performance hit.
When the data moves from value types to reference types its termed as ‘Boxing’ and the vice versa is termed as
‘UnBoxing’.
If you compile the above code and see the same in ILDASM you can see in the IL code how ‘boxing’ and ‘unboxing’
looks, below figure demonstrates the same.
Performance implication of Boxing and unboxing
In order to see how the performance is impacted we ran the below two functions 10,000 times. One function has
boxing and the other function is simple. We used a stop watch object to monitor the time taken.
The boxing function was executed in 3542 MS while without boxing the code was executed in 2477 MS. In other words
try to avoid boxing and unboxing. In project you always need boxing and unboxing , use it when it’s absolutely
necessary.
With the same article the sample code is attached which demonstrates this performance implication.
Currently I have not put a source code for unboxing but the same hold true for the same. You can write the same and
experiment it by using stopwatch class.