Professional Documents
Culture Documents
C# Notes by Meenu Chopra: The Answer Is "Yes" and "No"!
C# Notes by Meenu Chopra: The Answer Is "Yes" and "No"!
By
Meenu Chopra
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 wont
be any performance difference based on the language you write code.
3.1 Is it platform independent?
Many people ask this question Java is platform independent, what about .NET?.
The answer is Yes and No!
The code you write is platform independent, because whatever you write is getting
compiled into MSIL.
There is no native code, which depends on your operating system or CPU. But when
you execute the MSIL, the .NET framework in the target system will convert the MSIL
into native platform code. So, if you run your .NET exe in a Windows machine, the
.NET framework for Windows will convert it into Windows native code and execute.
If you run your .NET application in Unix or Linux, the .NET framework for Unix/Linux
will convert your code into Unix/Linux native code and execute. So, your code is purely
platform independent and runs anywhere!
But wait, we said it wrong there is no .NET framework for UNIX or Linux available
now.Microsoft has written the .NET framework only for Windows. If you or someone
else write a .NET framework for other platforms in future, your code will run there too.
So, let us wait until someone write .NET framework for Linux before you run your .NET
code in Linux.
Application
Libraries
CLR
.NET
Enterprise
Servers
.NET
Building
Block Services
C#, Visual Basic .NET
Visual Studio .NET
Windows OS (Win 32)
1.
2.
3.
4.
5.
6.
7.
8.
9.
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 assemblys 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: 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.
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.
The IL and the metadata are linked in assembly.
The compiler creates the .EXE or .DLL file.
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.
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.
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.
After translating the IL into native code, the converted code is sent to the .NET runtime
manager.
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.
Common Language Infrastructure (CLI)
The Common Language Infrastructure (CLI) is an open specification developed by Microsoft that
describes the executable code and runtime environment that allows multiple high-level languages to
be used on different computer platforms without being rewritten for specific architectures.
The common language Infrastructure (CLI) is a theoretical model of a development platform that
provides a device and language independent way to express data and behavior of applications.
The CLI specification describes the following four aspects: The Common Type System (CTS)
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.
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.
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 CPUindependent. 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 objects 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 doesnt 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 isnt 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
classs 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 thats 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 objects data and behavior. The objects 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 wont have direct access to the behaviors or data-but
rather those programs must make use of our objects 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 dont
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
1.
2.
3.
4.
Multilevel Inheritance:
public class A
{ }
public class B : A
{ }
public class C : B
Hierarchical
public class A
{ }
public class B : A
{ }
public class C : A
{ }
public class D : A
{ }
Multiple Inheritance:
{ }
public class A
{ }
public class B
{ }
public class C : A, B
{ }
Polymorphism
Polymorphism is the ability to define a method or property in a set of derived classes with matching
method signatures but provide different implementations and then distinguish the objects matching
interface from one another at runtime when you call the method on the base class.
It is a feature to use one name in many forms. It can be achieved in following ways: Method Overloading
Method Overriding
Method Hiding
1.
2.
3.
Method overriding and hiding makes use of the following three method keywords
new
virtual
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.
Remarks about Override
The override modifier is required to extend or modify the abstract or virtual implementation of
an inherited method, property, indexer, or event.
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 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 runtime 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;
}
Output: Value of a: 10
Value of b: 20
Parameterized constructor
Constructor that accepts arguments is known as parameterized constructor. There may be situations,
where it is necessary to initialize various data members of different objects with different values when
they are created. Parameterized constructors help in doing that task.
class Program
{
class C1
{
int a, b;
public C1(int x, int y)
{
this.a = x;
this.b = y;
}
public void display()
{
Console.WriteLine(Value of a: {0}, a);
Console.WriteLine(Value of b: {0}, b);
}
}
static void Main(string[] args)
{ // Here when you create instance of the class
// parameterized constructor will be called
C1 ob1 = new C1(10,20);
ob1.display();
Console.ReadLine();
}
}
Output: Value of a: 10
Value of b: 20
Private Constructor
Private constructors are used to restrict the instantiation of object using new operator. A private
constructor is a special instance constructor. It is commonly used in classes that contain static
members only.
If you dont want the class to be inherited we declare its constructor private.
We cant initialize the class outside the class or the instance of class cant be created outside if
its constructor is declared private.
We have to take help of nested class (Inner Class) or static method to initialize a class having
private constructor.
Example: class Program
{
class C1
{
int a, b;
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 cant 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 cant 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.
The general form of an operator function is as follows.
public static return_type operator op (argument list)
Where the op is the operator to be overloaded and operator is the required keyword.
Example: Overloading of Unary operator
class Complex
{
private int x;
private int y;
public Complex()
{}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine({0}\t{1},x,y);
}
public static Complex operator -(Complex c) //PASSING OBJECT
{
Complex temp = new Complex();
temp.x = -c.x;
temp.y = -c.y;
return temp;
}
}
class Program
{
static void Main(string[] args)
{
Complex c1 = new Complex(10, 20);
c1.ShowXY(); // displays 10 & 20
Complex c2 = new Complex();
c2.ShowXY(); // displays 0 & 0
c2 = -c1; //overloading unary operator
c2.ShowXY(); // diapls -10 & -20
Console.Read();
}
}
Output:
10 20
0 0
-10 -20
Namespace:
Namespaces are C# program elements designed to help you organize your programs. They also
provide assistance in avoiding name clashes between two sets of code.
In Microsoft .Net, Namespace is like containers of objects. They may contain unions, classes,
structures, interfaces, enumerators and delegates. Main goal of using namespace in .Net is for
creating a hierarchical organization of program. In this case, you need not to worry about the naming
conflicts of classes, functions, variables etc., inside a project.
In Microsoft .Net, every program is created with a default namespace. This default namespace is
called as global namespace. But the program itself can declare any number of namespaces, each of
them with a unique name. The advantage is that every namespace can contain any number of classes,
functions, variables and also namespaces etc., whose names are unique only inside the namespace.
The members with the same name can be created in some other namespace without any compiler
complaints from Microsoft .Net.
To declare namespace C# .Net has a reserved keyword namespace. If a new project is created in
Visual Studio .NET it automatically adds some global namespaces. These namespaces can be different
in different projects. But each of them should be placed under the base namespace System. The
names space must be added and used through the using operator, if used in a different project.
A namespace has the following properties:
They organize large code projects.
They are delimited with the . operator.
The using directive means you do not need to specify the name of the namespace for every
class.
The global namespace is the root namespace: global::system will always refer to the .NET
Framework namespace System.
Now have a look at the example of declaring some namespace:
namespace SampleNamespace
{
class SampleClass{}
interface SampleInterface{}
struct SampleStruct{}
enum SampleEnum{a,b}
delegate void SampleDelegate(int i);
namespace SampleNamespace.Nested
{
class SampleClass2{}
}
}
Within a namespace, you can declare one or more of the following types:
another namespace
class
interface
struct
enum
delegate
Namespaces implicitly have public access and this is not modifiable.
It is possible to define a namespace in two or more declarations. For example, the following example
defines two classes as part of the MyCompany namespace:
namespace MyCompany.Proj1
{
class MyClass
{
}
}
namespace MyCompany.Proj1
{
class MyClass1
{
}
}
Example: The following example shows how to call a static method in a nested namespace:
using System;
namespace SomeNameSpace
{
public class MyClass
{
static void Main()
{
Nested.NestedNameSpaceClass.SayHello();
}
}
// a nested namespace
namespace Nested
{
public class NestedNameSpaceClass
{
public static void SayHello()
{
Console.WriteLine(Hello);
}
}
}
}
Output
Hello
Example: Calling Nested Namespace Members
// Namespace Declaration
using System;
namespace Ex_nestedNamespace
{
namespace tutorial
{
class example
{
public static void MyPrint1()
{
Console.WriteLine(First Example of calling another namespace member.);
}
}
}
namespace Ex_NameSpace
{
class Program
{
static void Main(string[] args)
{
tutorial.example.MyPrint1();
tutorial.example1.MyPrint2();
Console.Read();
}
}
}
}
namespace Ex_nestedNamespace.tutorial
{
class example1
{
public static void MyPrint2()
{
Console.WriteLine(Second Example of calling another namespace member.);
}
}
}
Output:
First Example of calling another namespace member.
Second Example of calling another namespace member.
Interface
An Interface is a reference type and it contains only abstract members. Interfaces members can be
Events, Methods, Properties and Indexers. But the interface contains only declaration for its members.
Any implementation must be placed in class that realizes them. The interface can not contain
constants, data fields, constructors, destructors and static members. All the member declarations
inside interface are implicitly public and they cannot include any access modifiers.
An interface has the following properties:
An interface is like an abstract base class: any non-abstract type that implements the interface
must implement all its members.
{
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()
{
Obsolete
DllImport
Conditional
WebMethod
It is also possible to create new ones by extending the System.Attribute class.
For example:
using System;
[CLSCompliant(true)]
Public class myClass
{ // class code }
Web services also make use of attributes. The attribute [WebMethod] is used to specify that a
particular method is to be exposed as a web service.
Why Attributes ?
The reason attributes are necessary is because many of the services they provide would be very
difficult to accomplish with normal code. You see, attributes add what is called metadata to your
programs. When your C# program is compiled, it creates a file called an assembly, which is normally
an executable or DLL library. Assemblies are self-describing because they have metadata written to
them when they are compiled. Via a process known as reflection, a programs attributes can be
retrieved from its assembly metadata. Attributes are classes that can be written in C# and used to
decorate your code with declarative information. This is a very powerful concept because it means that
you can extend your language by creating customized declarative syntax with attributes.
How it is used in C#?
Attributes are elements that allow you to add declarative information to your programs. This
declarative information is used for various purposes during runtime and can be used at design time by
application development tools. For example, there are attributes such as DllImportAttribute that allow
a program to communicate with the Win32 libraries. Another attribute, ObsoleteAttribute, causes a
compile-time warning to appear, letting the developer know that a method should no longer be used.
When building Windows forms applications, there are several attributes that allow visual components
to be drag-n-dropped onto a visual form builder and have their information appear in the properties
grid. Attributes are also used extensively in securing .NET assemblies, forcing calling code to be
evaluated against pre-defined security constraints. These are just a few descriptions of how attributes
are used in C# programs.
Predefined .NET Valid Targets
Attribute
Description
AttributeUsage
Class
CLSCompliant
All
DllImport
Method
MTAThread
Method (Main)
NonSerialized
Field
Obsolete
ParamArray
Parameter
(array) parameter.
Serializable
STAThread
Method (Main)
ThreadStatic
Field (static)
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 its 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 Msword 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
doesnt 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();
}
}
}
-xxxxSocket 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.
Here is how to create the socket:
m_socListener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.IP);
AddressFamily is an enum defined in Sockets namespace.
Next we need to specify socket type: and we would use reliable two way connection-based
sockets (stream) instead of un-reliable Connectionless sockets ( datagrams) . So we obviously specify
stream as the socket type and finally we are using TCP/IP so we would specify protocol type as TCP.
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-xx-x-xxError 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-xx-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
Diagram to represent file-handling class hierarchy
The following table describes some commonly used classes in theSystem.IO namespace: Class Name
Description
FileStream
BinaryReader
BinaryWriter
StreamReader
StreamWriter
StringReader
StringWriter
DirectoryInfo
FileInfo
Description
Close
Flush
Clears all buffers for the current writer and causes any
buffered data to be written to the underlying stream.
Write
WriteLine
{
public void WriteData()
{
FileStream fs = new FileStream(c:\\test.txt, FileMode.Append,FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
Console.WriteLine(Enter the text which you want to write to the file);
string str = Console.ReadLine();
sw.WriteLine(str);
sw.Flush();
sw.Close();
fs.Close();
}
}
static void Main(string[] args)
{
FileWrite wr = new FileWrite();
wr.WriteData();
}
}
}
StreamReader Class
The StreamReader class is inherited from the abstract class TextReader. The TextReader class
represents a reader, which can read series of characters.
The following table describes some methods of the StreamReader class: Methods
Description
Close
Peek
Read
Reads the next character or the next set of characters from the
stream
ReadLine
Seek
str = sr.ReadLine();
}
Console.ReadLine();
sr.Close();
fs.Close();
}
}
static void Main(string[] args)
{
FileRead wr = new FileRead();
wr.ReadData();
}
}
}
Introduction to Web Services
A Web service exposes a number of methods that provide functionality that can be one or more
application, regardless of the programming languages, operating systems, and hardware platforms
used to develop them. The methods that provide such functionality are called Web Methods. The
functionality exposed by a Web service can be accessed by applications by using Internet Standards,
such as Simple Object Access Protocol (SOAP). SOAP is a protocol that uses extensible Markup
Language (XML) to describe data and HyperText Transfer Protocol (HTTP) to transmit application data.
An application that uses a Web service is called a Web Service Client.
A Web service is similar to a component that provides a specific functionality. However, components
uses object model-specific protocols, such as Internet Inter-ORB Protocol (IIOP) and Remote Method
Invocation (RMI), for communicating with client applications. This communication approach requires a
similar infrastructure at both client and the server sides. This approach is acceptable when the use of
components is confined to controlled environments. Web services use Internet Standards, such as
HTTP and XML, to communicate with client applications. This communication approach makes Web
services independent of any language or platform. Any computer that has access to the Internet can
easily access a Web service.
Depending on the requirements of a business, different types of Web services can be created and used
in an application.
Enabling Technologies used in Web Services
A web service can be created using any programming language in the .NET suite. There are certain
requirements need to be fulfilled to enable applications to access the functionality provided by Web
services. The requirements are: A common data representation format in order to ensure the interoperability of the data
exchanged by the client application and the Web service.
A standard method for sending messages from the client application to the Web service and
vice versa.
A standard format for describing the web service.
A mechanism to allow client applications to discover the Web services and their locations.
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.
UDDI (Universal Description Discovery and Integration)
UDDI provides a standard mechanism to register and discover a Web Service. When a Web service
provider wants to make a Web service available to client applications, the provider describes the web
service by using a WSDL document. Then, the provider registers the Web service in the UDDI
Directory. The UDDI directory contains pointers to the Web service and the WSDL document for the
Web service. Client applications can then discover the Web service by using the UDDI Directory.
UDDI
Registry
WSDL
Document
Locates a Web
Service
Client
Application
Web
Service
Describes
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.
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>
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.
Declaring Elements in a Document Type Definition
To represent data in a consistent format, it needs to be given a meaningful structure. A well-formed
document in XML may not necessarily have a meaningful structure. By defining the role of each
element in a formal model, known as Document Type Definition (DTD), users of XML can check that
each component of the document appears in a valid place in the XML document.
Document Type Definition (DTD)
DTD defines the structure of the content of an XML document, thereby allowing to store data in a
consistent format. It specifies the elements that can be resent in the XML document, attributes of
these elements, and their arrangement with relation to each other.
Creating a DTD is similar to creating a table in a database. In DTDs you specify the structure of data
by declaring elements to denote the data. This is similar to creating columns in a table.
XML allows you to create your own DTDs for applications. This gives you complete control over the
process of checking the content and structure of XML documents is created for an application. This
checking process is calledvalidation. XML document that conform to a DTD are considered valid
documents.
Declaring Elements in a DTD
In a DTD, elements are described using the following syntax: <! ELEMENT elementname (content-type or content-model/)>
In the given syntax,
Elementname specifies the name of the element.
Content-type or content-model specifies whether the element contains textual data or other
element.
Rule for Naming Elements and Attribute in XML
A name consists of at least one letter: a to z, or A to Z.
An element name may start with an underscore (_).
One or more letters, digits, hyphens, underscores or full stops can follow the initial letter.
Spaces and tabs are not allowed in element names, and the only punctuation signs allowed.
An element can be empty, unrestricted, or a container element. The following table describes each
type of element:
Element Type
Description
Empty
Unrestricted
Container
Description
PCDATA
ID
(enumerated)
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
REQUIRED
FIXED
IMPLIED
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 youre 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 memorys allocation and deallocation. CLR also allows you to write what is calledunsafe 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.
Compilation options to allow unsafe code
Unsafe code must be used on purpose and you must also provide the/unsafe option to
the csc.exe compiler to tell it that you are aware that the code you wish to compile contains zones
which will be seen as unverifiable by the JIT compiler. Visual Studio offers the Build Allow unsafe code
project property to indicate that you wish to use this compiler option.
Declaring unsafe code in C#
In C#, the unsafe keyword lets the compiler know when you will use unsafe code. It can be used in
three situations:
Before the declaration of a class or structure. In this case, all the methods of the type can use
pointers.
Before the declaration of a method. In this case, the pointers can be used within the body of this
method and in its signature.
Within the body of a method (static or not). In this case, pointers are only allowed within the marked
block of code. For example:
unsafe
{
}
Using pointers in C#
Each object, whether it is a value or reference type instance, has a memory address at which it is
physically located in the process. This address is not necessarily constant during the lifetime of the
object as the garbage collector can physically move objects store in the heap.
To create a pointer you can use the following declaration:
Type* variable_name;
As a type may be used each type that is not a reference-type field. It can be only: sbyte, byte, short,
ushort, int, uint, long, ulong, char, float, double etc.
Following examples show different pointers declarations:
int* pi; // declaration a pointer to integer variable
float* pf, pq // two pointers to float variables
char* pz // pointer to char
Advantages of UNSAFE in C#
Performance and flexibility, by using pointer you can access data and manipulate it in the most
efficient way possible.
Compatibility, in most cases we still need to use old windows APIs, which use pointers
extensively, or third parties may supply DLLs that some of its functions need pointer parameters.
Although this can be done by writing the DLLImport declaration in a way that avoids pointers, but in
some cases its just much simpler to use pointer.
Memory Addresses, there is no way to know the memory address of some data without using
pointers.
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 doesnt 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 dont 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
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
{
1.
2.
3.
4.
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:
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.
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.
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.
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.
The ADO.NET Object Model
ADO.NET uses a structured process flow containing components. The structured process flow or the
object model is shown in following figure:
Connection
Data Reader
Command
Data Adapter
.NET Application
DataSet
Database
Data Provider
Accessing
Retrieved data
Accessing retrieved data
Filling dataset with data
Establish connection
Executes a command to retrieve data
Transfer data to the dataset and reflects the changes in dataset
Retrieve data in a read-only, forwarded only
ADO.NET Object Model
Data Access in ADO.NET relies on two components: DataSet and Data Provider.
DataSet
The dataset is a disconnected, in-memory representation of data. It can be considered as a local copy
of the relevant portions of the database. The DataSet is persisted in memory and the data in it can be
manipulated and updated independent of the database. When the use of this DataSet is finished,
changes can be made back to the central database for updating. The data in DataSet can be loaded
from any valid data source like Microsoft SQL server database, an Oracle database or from a Microsoft
Access database.
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 Microsofts 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
Component classes that make up the Data Providers
The Connection Object
The Connection object creates the connection to the database. Microsoft Visual Studio .NET provides
two types of Connection classes: the SqlConnection object, which is designed specifically to connect to
Microsoft SQL Server 7.0 or later, and the OleDbConnection object, which can provide connections to a
wide range of database types like Microsoft Access and Oracle. The Connection object contains all of
the information required to open a connection to the database.
The Command Object
The Command object is represented by two corresponding classes: SqlCommand and OleDbCommand.
Command objects are used to execute commands to a database across a data connection. The
Command objects can be used to execute stored procedures on the database, SQL commands, or
return complete tables directly. Command objects provide three methods that are used to execute
commands on the database:
ExecuteNonQuery: Executes commands that have no return values such as INSERT, UPDATE or
DELETE
ExecuteScalar: Returns a single value from a database query
ExecuteReader: Returns a result set by way of a DataReader object
The DataReader Object
The DataReader object provides a forward-only, read-only, connected stream recordset from a
database. Unlike other components of the Data Provider, DataReader objects cannot be directly
instantiated. Rather, the DataReader is returned as the result of the Command objects ExecuteReader
method. The SqlCommand.ExecuteReader method returns a SqlDataReader object, and the
OleDbCommand.ExecuteReader method returns an OleDbDataReader object. The DataReader can
provide rows of data directly to application logic when you do not need to keep the data cached in
memory. Because only one row is in memory at a time, the DataReader provides the lowest overhead
in terms of system performance but requires the exclusive use of an open Connection object for the
lifetime of the DataReader.
here.
Image taken from http://michaelbungartz.wordpress.com/
What goes inside when you declare a variable?
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.
Stack and Heap
In order to understand stack and heap, lets 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();
}
Its a 3 line code so lets 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 its 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, cant 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 its 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 its 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.
So which data types are ref type and value type?
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 whats 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 its 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.