Beruflich Dokumente
Kultur Dokumente
Static variables
Variable of instance
Array's elements
Parameters given by reference
Parameters given by value
Returned values
Local variables.
Static Variables will be alive throughout the life of a program. It can be declared using static
modifier.
An Instance variable is a variable declared without static modifier. Usually it is declared inside a
class or structure definition.
Parameter Values can be viewed as input parameters into methods:
public static void Sum(int a, int b)
{
Console.WriteLine("The sum of elements {0} and {1} is {2}",a,b,a + b);
}
This code writes in console values of variables a, b and their summary value. Now if the values
of these parameters are modified inside the method, this change will not be reflected inside the
main function. It is because the compiler creates copies of them when it passes them as value
types. This ensures that their original values are not modified.
Instead if one wants to modify the parameter variables inside the function, C# has something
called Reference variables. Reference variables also have a modifier out which can be used
before their type. Look at the following example:
public static void SumRef(ref int a, ref int b)
{
a = 4;
b = 6;
Console.WriteLine("The sume of elements {0} and {1} is {2}",a,b,a + b);
}
Now this method modifies the value of variables a and b with values 4 and 6. These values are
retained even after the execution of the function gets completed.
If the parameters need to be returned then they can be qualified with out modifier or as returned
parameter in method definition. Here is an example of both of them, in which both of them return
the same value:
public static int SumOut(int a, int b, out int sum1)
{
sum1 = a+b;
Console.WriteLine("The sum1 of elements {0} and {1} is {2}",a,b,a+b);
return sum1;
}
In main function it must be called in the next manner:
int sume ;
sume = SumeOut(2,2, out sume);
Constants in C#:
Constant type of data cannot be changed. To declare a constant the keyword const is used. An
example for the constant declaration is: const double PI = 3.1415;
Values types in C#:
Value type stores real data. When the data are queried by different function a local copy of it
these memory cells are created. It guarantees that changes made to our data in one function
don't change them in some other function. Let see at a simple example:
public class IntClass
{
public int I = 1;
}
Here we have simple class that contains only one public data field of integer type. Now have a
look on its usage in main function:
arr[2] = m_z;
return arr;
}
}
The above is declaration for a simple structure of real 3D point. As you see a class declaration
looks very similar to the struct except that the class also has a constructor.
Enumerated types can be used to create some set of identifiers that can have values of simple
type. Let us see at example of enum type:
public enum Days
{
Monday,
Tuesday,
Wensday,
Thursday,
Friday,
Saturday,
Sunday
}
In example there are enum that has days of week names. The values of days by default are in
range from 0 to 6.
Common types in C#:
Object in C# language is universal; it means that all supported types are derived from it. It
contains only a couple of methods: GetType() - returns a type of object, ToString() returns string
equivalent of type that called.
Next type is class. It is declared in the same manner as structure type but it has more advanced
features.
Interface is an abstract type. It is used only for declaring type with some abstract members. It
means members without implementations. Please, have a look at piece of code with a declaration
for a simple interface:
interface IRect
{
int Width
{
get;
set;
}
int Height
{
get;
set;
}
int CalculateArea();
}
The members of interface can be methods, properties and indexers.
Next reference type to be dealt is delegate. The main goal of delegate usage is encapsulation
of methods. It most like at pointers to function in C++.
String is common type that is used in almost all programming languages of high level. An
example of string declaration and initialization:
string s = "declaration and init";
The last very used reference type is array. Array it is set of elements that have the same type.
Array contains list of references on memory cells and it can contain any amount of members. In
C# there are three types of arrays: one-dimensional, two-dimensional and jagged array.
So, this covers almost all types used in C#. All these types can be cast to another type using
special rules. An implicit casting can be done with types when values of variables can be
converted without losing of any data. There is special type of implicit casting called boxing. This
enables us to convert any type to the reference type or to the object type. Boxing example:
// boxing
char ch = 'b';
object obj = ch;
Console.WriteLine("Char value is {0}",ch);
Console.WriteLine("Object value is {0}",obj);
Console.WriteLine();
This piece of code prints the same values of integer type variable and object type variable. The
opposite process to the boxing is un-boxing. An example for un-boxing is as follows.
// unboxing
float q = 4.6f;
object ob = q;
Console.WriteLine("Object value is {0}",ob);
float r = (float)ob;
Console.WriteLine("Float value is {0}",r);
So, it is main item of common data type creating and using. All sources are attached. To
compile and run it need to run .NET command line. Just type: csc DataTypes.cs. It creates
DataTypes.exe that can be run as standard executable file.
You can get the strings of Microsoft Intermediate Language code using ILDasm:
IL_0014: stloc.0
IL_0015: ldloc.0
IL_0016: ldc.r8 0.0
IL_001f: bge.un.s IL_002d
IL_0021: ldc.r8 0.0
IL_002a: stloc.1
IL_002b: br.s IL_0031
IL_002d: ldloc.0
IL_002e: stloc.1
IL_002f: br.s IL_0031
IL_0031: ldloc.1
IL_0032: ret
} // end of method Aperture::GetVolume
To clearly understand that IL really is immediately language you should write the same code in
VB .NET and look at these two sources in IL. These methods will be almost identical.
The main advantages of IL are:
1. IL isn?t dependent on any language and there is a possibility to create applications with
modules that were written using different .NET compatible languages.
2. Platform independence - IL can be compiled to different platforms or operating systems.
OOP & C#
The skeleton of object - oriented programming is of course the concepts of class. This C#
tutorial 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.
All the programming languages supporting Object oriented Programming will be supporting
these three main concepts:
1. Encapsulation
2. Inheritance
3. Polymorphism
Encapsulation in C#:
Encapsulation is process of keeping data and methods together inside objects. In this way
developer must define some methods of object?s interaction. In C# , encapsulation is realized
through the classes. A Class can contain data structures and methods. Consider the following
class.
In this example we encapsulate some data such as height, width, thickness and method
GetVolume. Other methods or objects can interact with this object through methods that have
public access modifier. It must be done using ?.? operator.
Inheritance in C#:
In a few words, Inheritance is the process of creation new classes from already existing
classes. The inheritance feature allows us to reuse some parts of code. So, now we have some
derived class that inherits base class?s members. Consider the following code snippet:
As you see to inherit one class from another, we need to write base class name after ?:?
symbol. Next thing that was done in code Door () ? constructor also inherits base class
constructor. And at last we add new private field. All members of Aperture class are also in Door
class. We can inherit all the members that has access modifier higher than protected.
Polymorphism in C#:
Polymorphism is possibility to change behavior with objects depending of object?s data type. In
C# polymorphism realizes through the using of keyword virtual and override. Let look on the
example of code:
Now we need to re-define it in our derived Door class. The usage of virtual methods can be
clarified when we creating an instance of derived class from the base class:
Aperture ap = new Door();
ap.Out();
In such cases, the runtime keeps record of all the virtual function details in a table called
VMT(Virtual Method Table) and then in runtime dynamically picks the correct version of the
function to be used. Here it uses Out() method from derived class of course.
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.
Please now have a look at the example of declaring some namespace:
using System;
namespace OutNamespace
{
namespace WorkNamespace
{ /// can be placed some classes, structures etc.
}
}
In this example we create two namespaces. These namespaces have hierarchical structure.
We have some outer one named OutNamespace and the inner one called WorkNamespace. The
inner namespace is declared with a C# .Net class WorkItem.
The next logical discussion after a namespace is classes. A class is the basis of object ?
oriented programming. It encapsulates the data and methods into one itself and manipulates
them through the interaction with that object.
class WorkItem
{
public WorkItem()
{
}
static WorkItem()
{
m_counter = 1;
}
public static int GetCounter()
{
return m_counter;
}
private static int m_counter;
public virtual void Status()
{
}
internal bool IsWorking
{
get
{
return m_isWorking;
}
set
{
m_isWorking = value;
}
}
private bool m_isWorking = true;
}
The above sample contains the .Net namespace with the class WorkItem inside it.
As already discussed, a class is the basis of Object oriented programming. A class must have a
constructor. The constructor method is used for initialization purposes. Each class can have
different modifiers which pertains to the type and functionality of the class. Some such modifiers
are: new, public, protected, internal, private, abstract, and sealed. A class members can also
have these modifiers. In the above example, there is declared special constructor type ? static
constructor. It uses only for class not for its instances. In the same way we can access to the
static members of class.
OutNamespace.WorkNamespace.WorkItem item = new WorkItem();
int i = WorkItem.GetCounter();
In this piece of code there was created some instance of WorkItem but called using its full name
(including all namespace?s names). The second line it is an access to the public static property of
WorkItem. There are many advanced features that can be used in class constructing process.
One of them polymorphism that can be realized though the virtual methods.
.Net Framework basics
When we speak about .Net, we mean by .NET framework. .NET Framework is made up of the
Common Language Runtime (CLR), the Base Class Library (System Classes). This allows us to
build our own services (Web Services or Windows Services) and Web Applications (Web forms
Or Asp .Net), and Windows applications (Windows forms). We can see how this is all put
together.?
Above Picture shows overall picture, demonstrating how the .NET languages follows rules
provided by the Common Language Specifications (CLS). These languages can all be used?
Independently to build application and can all be used with built-in data describers (XML) and
data assessors (ADO .NET and SQL). Every component of the .NET Framework can take
advantage of the large pre- built library of classes called the Framework Class Library (FCL).
Once everything is put together, the code that is created is executed in the Common Language
Runtime. Common Language Runtime is designed to allow any .NET-compliant language to
execute its code. At the time of writing, these languages included VB .Net, C# and C++ .NET, but
any language can become .NET- compliant, if they follow CLS rules. The following sections will
address each of the parts of the architecture.
.Net Common Language Specifications (CLS):
In an object-oriented environment, everything is considered as an object. (This point is
explained in this article and the more advanced features are explained in other articles.) You
create a template for an object (this is called the class file), and this class file is used to create
multiple objects.
TIP: Consider a Rectangle. You may want to create many Rectangle in your lifetime; but each
Rectangle will have certain characteristics and certain functions. For example, each rectangle will
have a specific width and color. So now, suppose your friend also wants to create a Rectangle.
Why reinvent the Rectangle? You can create a common template and share it with others. They
create the Rectangle based on your template. This is the heart of object-oriented programming?
the template is the class file, and the Rectangle is the objects built from that class. Once you
have created an object, your object needs to communicate with many other Objects.
Even if it is created in another .NET language doesn?t matter, because each language follows
the rules of the CLS. The CLS defines the necessary things as common variable types (this is
called the Common Type System CTS ), common visibility like when and where can one see
these variables, common method specifications, and so on. It doesn?t have one rule which tells
how C# composes its objects and another rule tells how VB .Net does the same thing . To steal a
phrase, there is now ?One rule to bind them all.? One thing to note here is that the CLS simply
provides the bare rules. Languages can adhere to their own specification. In this case, the actual
compilers do not need to be as powerful as those that support the full CLS.
The Common Language Runtime (CLR):
The heart of .net Framework is Common Language Runtime (CLR). All .NET-compliant
languages run in a common, managed runtime execution environment. With the CLR, you can
rely on code that is accessed from different languages. This is a huge benefit. One coder can
write one module in C#, and another can access and use it from VB .Net. Automatic object
management, the .NET languages take care of memory issues automatically. These are the few
listed?benefits which you get from CLR.
Microsoft Intermediate Language (MSIL):
So how can many different languages be brought together and executed together??Microsoft
Intermediate Language (MSIL) or, as it?s more commonly known, Intermediate Language (IL). In
its simplest terms, IL is a programming language.?If you wanted to, you could write IL directly,
compile it, and run it. But why would want to write such low level code? Microsoft has provided
with higher-level languages, such as C#, that one can use. Before the code is executed, the MSIL
must be converted into platform-specific code. The CLR includes something called a JIT compiler
in which the compiler order is as follows.
Source Code => Compiler => Assembley =>Class Loader =>Jit Compiler =>Manged Native
Code=>Execution.
The above is the order of compilation and execution of programs. Once a program is written in a
.Net compliant language, the rest all is the responsibility of the frame work.
C# Methods:
Method is object-oriented item of any language. All C# programs are constructed from a number
of classes and almost all the classes will contain methods. A class when instantiated is called an
object. Object-oriented concepts of programming say that the data members of each object
represent its state and methods represent the object behavior.
return m_name;
}
public string HowOldAreYou()
{
Console.WriteLine(m_old.ToString());
return m_old;
}
}
The private members m_old and m_name define some state of objects that can be created as
instances of our class. Also the class Man has two methods, which serve some of our requests.
Method string WhatIsYourName() writes current object?s name to the console and returns it, and
the second one similar to first return age of man and also writes an output to the console.
The return type in the example above returns strings, which is an in-built data type. The
methods can also return any generic C# type or any custom types created by us.
Passing Parameters to Methods in C#:
The input parameters can be passed in two ways.
Value type
Reference type.
If parameters are passed as value types a new copy of it will be created and passed inside the
function. If they are created as reference types, only the address of the parameters will be
passed.
See next example:
public int CalculateBirthYear(int year)
{
int b = year - m_old;
Console.WriteLine("Birth year is {0}",b);
return b;
}
If input parameter pass as reference type it must use keyword ref, in that way we operate with
the same cell in memory. That?s mean it can be changed inside any method. A small example for
a parameter passed by reference is:
public int CalculateBirthYear(ref int year)
{
int b = year - m_old;
Console.WriteLine("Birth year is {0}",b);
return b;
}
Now, the function CalculateBirthYear can even modify the value of year as it is passed by
reference.
This is not supported in C++ though it can be achieved by using some programming tricks. In C#
the output parameter is declared with the keyword out before the data type. A typical example is
as follows.
public void CalculateBirthYear(ref int year, out int birthyear)
{
int b = year - m_old;
Console.WriteLine("Birth year is {0}",b);
birthyear = b;
return;
}
Strictly speaking there is no difference between ref and out parameters. The only difference is
that the ref input parameters need an input value and the out parameters don?t.
Property in C#:
Property ? it is a special method that can return a current object?s state or set it. Simple syntax of
properties can see in the following example:
public int Old
{
get {return m_old;}
set {m_old = value;}
}
public string Name
{
get {return m_name;}
}
Here are two types of properties. A first one can set or get field of class named m_old, and the
second is read only. That?s mean it can only get current object?s state.
The significance of these properties is its usability. These properties need not be called with any
function names like objectname.get or objectname.set etc., But they can be directly assigned the
values or retrieve the values.
class Hello
{
public static void main(String args[])
{
System.out.println("Hello");
}
}
class Hello
{
Hello()
{
// 0 0:aload_0
// 1 1:invokespecial #1 <Method void Object()>
// 2 4:return
}
public static void main(String args[])
{
System.out.println("Hello");
// 0 0:getstatic #2 <Field PrintStream System.out>
// 1 3:ldc1 #3 <String "Hello">
// 2 5:invokevirtual #4 <Method void PrintStream.println(String)>
// 3 8:return
}
}
To understand this you must have some knowledge of computer internals concepts for eg.
Opcodes, instruction templates etc. I assume that you already know them.
As usual this code will also start with main method. The first line tells that print ?Hello? it is a
normal print statement. A specific instruction, with type information, is built by replacing the ?T? in
the instruction template in the opcode column by the letter in the type column. In this case it is a
load instruction for type reference.
Invokespecial instruction must name an instance initialization method, a method in the current
class, or a method in a superclass of the current class. Class and interface initialization methods
are invoked implicitly by the Java virtual machine; they are never invoked directly from any Java
virtual machine instruction, but are invoked only indirectly as part of the class initialization
process.
invokevirtual or invokespecial is used to access a protected method of a superclass, then the type
of the class instance being accessed must be the same as or a subclass of the current class.
The Java virtual machine uses local variables to pass parameters on method invocation. On
class method invocation any parameters are passed in consecutive local variables starting from
local variable 0.
C# Hello Program:
using System;
class Hello
{
public static void Main(string[] args)
{
Console.WriteLine("Hello");
}
}
[AttributeUsage(AttributeTargets.All)]
public class ProductInfo : System.Attribute
{
public ProductInfo(double version,string name)
{
m_version = version;
m_authorName = name;
}
There is a new item in the first line of code. It is an attribute that allows us to use a c# attribute
keyword AttributeUsage to all elements of our class (parameter AttributeTargets.All).
Now we can use these c# attributes in declaration of any other custom class:
[ProductInfo(1.005,"CoderSource"])
public class AnyClass { }
After creating simple custom type c# attributes, we can get information about all its attributes at
runtime. Such run-time information can be pulled out from a class by using the namespace
System.Reflection. In main function of our C# tutorial program we can get from our object all
information about custom attributes. Next piece of code demonstrate it:
MemberInfo membInfo;
membInfo = typeof(AnyClass);
object [] attributes;
attributes = membInfo.GetCustomAttributes(typeof(ProductInfo),true);
if(attributes.GetLength(0)!=0)
{
ProductInfo pr = (ProductInfo) attributes[0];
Console.WriteLine("Product author: {0}",pr.AuthorName);
Console.WriteLine("Product version; {0}",pr.Version);
}
Using standard methods of getting type information and members of his type we can get all
custom attributes.
The example in this C# tutorial uses only one of three library c# attributes (AttributeUsage). It
uses only with declaration some custom c# attribute. There is another standard attribute called
Conditional. It calls method with that attribute only in case when method application has some
needed condition. Most often it is used to define some preprocessor commands (?#?). And the
last reserved attribute is Obsolete. It helps us to mark some elements of program that are old to
use. These are basic things about attributes and their usage in applications.
1. Using the throw operator. It call the manage code anyway and process an exception.
2. If using the operators goes awry, it can generate an exception.
Simple Exceptions - .Net C# Tutorial:
C# language uses many types of exceptions, which are defined in special classes. All of them
are inherited from base class named System.Exception. There are classes that process many
kinds of exceptions: out of memory exception, stack overflow exception, null reference exception,
index out of range exception, invalid cast exception, arithmetic exception etc. This c# tutorial
deals with DivideByZero c# exception and custom classes in c# exceptions.
C# has defined some keywords for processing exceptions. The most important are try, catch
and finally.
The first one to be known is the try operator. This is used in a part of code, where there exists a
possibility of exception to be thrown. But operator ?try? is always used with the operators: catch
and finally.
See the following example of handling a simple exception in c#.
This code in runtime throws a DivideByZeroException and writes some message through the
console. But if you want to release some resources that were created you must use try ? finally
construction. Finally will be called even if there were no exceptions raised.
In the similar way we can use try ? catch ? finally construction. The attached c# tutorial program
contains sample including all the three.
Custom Exception Classes - C# Tutorial:
Some larger projects might have a requirement of creating their own custom exception classes.
Let us try to create class that validates email address. It will validate for the ?@? symbol. Please
have a look on the following piece of code:
Here were created a C# .Net TextException class that inherits from System.Exception class
of .NET class library. Actually it does nothing, but there is an additional class MailValidator. It has
TestEnteredMail method that raises a TextException. Now look at usage of it in Main function.
try
{
MailValidator.TestEnteredMail(Console.ReadLine());
}
catch(TextException)
{
So, if user enters mail address without it throws an exception. All the sources are attached and
compliable. The example can be compiled using .NET command line through the csc command
line program. You only need to type csc filename.cs.
}
float CalculateArea();
}
The above INode interface has declared a few abstract properties and function which should be
implemented by the derived classes.
//Sample for Deriving a class using a C# .Net interface - c# tutorial
public class Node : INode
{
public Node()
{}
public string Text
{
get
{
return m_text;
}
set
{
m_text = value;
}
}
private string m_text;
public object Tag
{
get
{
return m_tag;
}
set
{
m_tag = value;
}
}
private object m_tag = null;
public int Height
{
get
{
return m_height;
}
set
{
m_height = value;
}
}
private int m_height = 0;
public int Width
{
get
{
return m_width;
}
set
{
m_width = value;
}
}
private int m_width = 0;
public float CalculateArea()
{
if((m_width<0)||(m_height<0))
return 0;
return m_height*m_width;
}
}
Now the above code has created a c# class Node that inherits from INode c# interface and
implement all its members. A very important point to be remembered about c# interfaces is, if
some interface is inherited, the program must implement all its declared members. Otherwise the
c# compiler throws an error.
The above code was a simple example of c# interface usage. Now this has to be followed with
some advanced details of interface building in C# .Net. The previous example used only names
of methods or properties that have the same names as in interface. But there is another
alternative method for writing the implementation for the members in class. It uses full method or
property name e.g. INode.CalculateArea () {// implemetation}.
Multiple Inheritance using C# interfaces:
Next feature that obviously needs to be explained is multiple inheritance using c# interfaces.
This can be done using child class that inherits from any number of c# interfaces. The inheritance
can also happen with a combination of a C# .Net class and c# interfaces. Now let us see a small
piece of code that demonstrate us multiple inheritance using only interfaces as parent data types.
class ClonableNode : INode,ICloneable
{
public object Clone()
{
return null;
}
// INode members
}
The above example created a class ClonableNode. It implements all the functionality of INode
interface in the same way as it was done in Node class. Also it realizes Clone method only one
item of IClonable interface of .NET library.
is Operator for C# .Net interfaces - C# Tutorial:
At last a new C# operator that can be used to define that class should be explained. It is the is
operator. Look at the following piece of code:
if(nodeC is INode)
Console.WriteLine("nodeC is object of INode type");
else
Console.WriteLine("nodeC isn't object of INode type");
In example nodeC object was created as ClonableNode type, but when we run program "if
operator" returns true. It means that nodeC also is of INode type.
There is a new keyword lock inside the above chunk of .Net C# tutorial code. This provides a
mechanism for synchronizing the thread operation. It means at the same point of time only one
thread can access to this method of created object. Unless the lock is released after completion
of the code, the next routine or iteration cannot enter the block.
To understand it more clearly please have a look at the piece of main method?s code:
As you see there were created three additional threads. These threads start a method of object
that has Launcher type. The above program is a very simple example of using multi-threading in
C#. Net. But C# .Net allows us to create more powerful applications with any level of complexity.
At first we should get type of object that was created. The following C# .Net code snippet shows
how to do it.
TestDataType testObject = new TestDataType(15);
Type objectType = testObject.GetType();
Now objectType has all the required information about class TestDataType. We can check if our
class is abstract or if it is a class. The System.Type contains a few properties to retrieve the type
of the class: IsAbstract, IsClass. These functions return a Boolean value if the object is abstract
or of class type. Also there are some methods that return information about constructors and
methods that belong to the current type (class). It can be done in a way as it was done in next
example:
Now, the above program returns a list of methods and constructors of TestDataType class.
Reflection is a very powerful feature that any programming language would like to provide,
because it allows us to get some information about objects in runtime. It can be used in the
applications normally but this is provided for doing some advanced programming. This might be
for runtime code generation (It goes through creating, compilation and execution of source code
in runtime).
The Sample code can be downloaded from here. The attached example can be compiled
using .NET command line csc command. Type csc Reflection.cs. This will create the executable
Reflection.exe, which can be run as a normal executable.
COM Interop
The ultimate goal of COM Interop is to provide access to the existing COM components
without requiring that the original component be modified. This tries to make the .NET
types equivalent to the COM Types.
{
m_xPos = - m_xPos;
}
public void InvertY()
{
m_yPos = - m_yPos;
}
public void InvertZ()
{
m_zPos = - m_zPos;
}
private float m_xPos = 0;
private float m_yPos = 0;
private float m_zPos = 0;
}
Now, we have a class named Figure and it has three private fields that use to store position and
three methods to invert this position by every axis. In main class we declare delegate as follows:
public delegate void FigureDelegate();
And now in the main function we should use it like this:
Figure figure = new Figure(10,20,30);
FigureDelegate fx = new FigureDelegate(figure.InvertX);
FigureDelegate fy = new FigureDelegate(figure.InvertY);
FigureDelegate fz = new FigureDelegate(figure.InvertZ);
MulticastDelegate f_del = fx+fy+fz;
In this example we create three delegates of FigureDelegate type and attach to these elements
our three methods from Figure class. Now every delegate keeps the address of the attached
function. The last line of code is very interesting, here we create a delegate of base type
(MulticastDelegate) and attach three of our already created delegates. As all our methods are of
void return type they are automatically of type MutlticastDelegate and a MulticastDelegate can
support multiple methods invocation also. Hence we can write
Figure figure = new Figure(10,20,30);
FigureDelegate fMulti = new FigureDelegate(figure.InvertX);
fMulti += new FigureDelegate(figure.InvertY);
fMulti();
Events in C# .Net:
Delegate usefulness does not just lie in the fact that it can hold the references to functions but in
the fact that it can define and use function names at runtime and not at compile time. A large goal
of design delegates is their applicability in events model of .Net. Events are the actions of the
system on user manipulations (e.g. mouse clicks, key press, timer etc.) or any event triggered by
the program. To understand the usage of delegates for event model, the previous examples are
used here. We should add to our Figure class next things:
public delegate void FigureHandler(string msg);
public static event FigureHandler Inverted;
public void InvertZ()
{
m_zPos = - m_zPos;
Inverted("inverted by z-axis");
}
Now we have a delegate declared and event that uses this delegate's type. In every function we
should call our event. The next code snippet should explain it clearly:
static void Main(string[] args)
{
Figure figure = new Figure(10,20,30);
Figure.Inverted+=new Test.Figure.FigureHandler(OnFigureInverted);
figure.InvertX();
figure.InvertZ();
}
private static void OnFigureInverted(string msg)
{
Console.WriteLine("Figure was {0}",msg);
}
So, in the main function we should create an object of figure class and attach event handler to
the method OnFigureInverted. And when we call any of invert methods the event is fired and it
calls our event handler. The application will print the following string into the console: Figure was
inverted by x-axis Figure was inverted by z-axis There was simple examples of using delegates
and events and should be treated as a starting point to learn it more yourself. Download the C#
Delegates source files from the link. To compile and run it need to run .NET command line. Just
type: csc TestClass.cs. It creates TestClass.exe that can be run as standard executable file.
C# Method Overloading
Last Update: 9 February, 2005
In complex applications written in C#, we may need many methods which do essentially similar
functions but are just different enough to be considered unique. For example, we may have to
calculate a person's tax liability and would need to implement a method for doing this calculation
in our application program. However, there are many different rules when it comes to tax
calculations and they vary throughout the world. While there may be many rules, one basic
equation stays the same: Your net income equals your gross income minus a computed tax
amount. It is the method of computing your tax that varies.
We would probably have to implement different methods for each type of tax calculation. And, we
could give each method a unique name such as TaxCalc1, TaxCalc2, TaxCalc3, etc. But
wouldn't it be nice to just name the method TaxCalc and pass different arguments to it based on
the computation desired?
For instance, let's say you live in a region within your country where you are taxed on your
personal income, the value of your home, and any income you generate by doing business. On
sales you generate through business activity, you must pay a gross receipts tax on all sales. If
you own your home, you must pay a property tax on the imputed value of it. Then lastly, you must
pay a tax on all income you generate through a job with another employer.
An Example: Tax Calculation
For this article, we will use a hypothetical example of computing various taxes on a person's
property, sales, and income. Let's summarize the logical flow through pseudocode:
HV = Home_Value
HR = Home_Tax_Rate
GS = Gross_Sales
GR = Gross_Sales_Tax_Rate
PI = Personal Income
If YOU_OWN_YOUR_OWN_HOME and DO_NOT_OWN_A_BUSINESS THEN
Tax = TaxCalc(HV,HR) ' Calculate tax on the home's value
ELSE
If YOU_DO_NOT_OWN_YOUR_OWN_HOME and OWN_A_BUSINESS THEN
Tax = TaxCalc(GS,GR) ' Calculate tax on your gross receipts from sales
ELSE
If YOU_OWN_YOUR_OWN_HOME and OWN_A_BUSINESS THEN
Tax = TaxCalc(HV,HR,GS,GR) ' Calculate tax on both your home and gross receipts
ENDIF
ENDIF
ENDIF
Tax = Tax + TaxCalc(PI) ' And everyone gets a tax calculation on personal income
The pseudo code says that if you own your own home but do not have a business, then you will
calculate your tax based on the home's value and the tax rate on a home. If you don't own a
home but you own a business then you will calculate your tax based on your gross sales and
gross sales tax rate. Finally, if you own a home and a business then you will call TaxCalc and
pass all four values. Everyone is run through the TaxCalc method for personal income tax. We
don't have to pass a rate for personal income tax calculation because everyone is at a fixed rate
which is embedded within the method.
Keep in mind that this example of tax calculation is all hypothetical. Tax codes and calculations,
as you know, are much more complex than what is described here throughout the world. But for
the sake of this example, we see that we have a method named TaxCalc that is able to take one,
two, or four arguments based upon the type of tax we are calculating. Without method
overloading, we would have to create a unique method name for each type of calculation we
would have to do. We would probably name each TaxCalc1, TaxCalc2, and TaxCalc3 respectively.
How does C# know which method to call? It's easy. It knows which method to invoke based on
the number and type of arguments passed to it. This is also referred to as the signature of the
method. If C# sees you are calling TaxCalc with four arguments, then it will call that method with
four receiving arguments. The same is true for the other two methods as well.
inputs = Console.ReadLine();
gs = Convert.ToDouble(inputs);
Console.WriteLine("What is the gross sales tax rate?");
inputs = Console.ReadLine();
gr = Convert.ToDouble(inputs);
}
if (ownshome && !ownsbusiness)
totaltax = TaxCalc(hv, hr);
else
if (!ownshome && ownsbusiness)
totaltax = TaxCalc(gs, gr);
else
if (ownshome && ownsbusiness)
totaltax = TaxCalc(hv, hr, gs, gr);
Console.WriteLine("How much did you make last year?");
inputs = Console.ReadLine();
pi = Convert.ToDouble(inputs);
totaltax = totaltax + TaxCalc(pi);
Console.WriteLine("Your total tax is {0}", totaltax);
pitaxrate = TaxCalc("TaxTable1");
Console.WriteLine("Personal tax rate is {0}", pitaxrate);
} // *** Main ***
Conclusion
Method overloading is a powerful concept in C# in that it helps to simplify code reusability and
clarity. If our example method of TaxCalc was placed in a .dll file somewhere, I would only have to
remember that I have to call TaxCalc and only fill in the appropriate arguments to pass. Without
method overloading, I would have to try and remember which specific uniquely-named method to
call. This would present a problem if you do not code everyday using a particular method in that
time would be spent getting familiar with the methods all over.
Reflection in C#
This article is aimed to explain reflection in .NET Framework.
Reflection is one of the features of .Net framework and has greater importance during the
development of large applications. In brief it is a powerful way of collecting and
manipulate information present in application's assemblies and its metadata. Metadata
contain all the Type information used by the application. The ability to obtain
information at runtime also makes it even more advantageous. When reflection is used
along with system.type, it allows the developer to get the valuable information about all
the types and about the assemblies. We can even create the instances and then invoke
various types that are used across the application.
What is Reflection?
Reflection is the ability to find out information about objects, the application details
(assemblies), its metadata at run-time.
This allows application to collect information about itself and also manipulate on itself.
It can be used effectively to find all the types in an assembly and/or dynamically invoke
methods in an assembly. This includes information about the type, properties, methods
and events of an object and to invoke the methods of object Invoke method can be used
too. With reflection we can dynamically create an instance of a type, bind the type to an
existing object, or get the type from an existing object and invoke its methods or access
its fields and properties. If Attributes (C#) are used in application, then with help of
reflection we can access these attributes. It can be even used to emit Intermediate
Language code dynamically so that the generated code can be executed directly.
How to use Reflection in our applications?
System.Reflection namespace contains all the Reflection related classes. These classes
are used to get information from any of the class under .NET framework. The Type class
is the root of all reflection operations. Type is an abstract base class that acts as means to
access metadata though the reflection classes. Using Type object, any information related
to methods, implementation details and manipulating information can be obtained. The
types include the constructors, methods, fields, properties, and events of a class, along
with this the module and the assembly in which these information are present can be
accessed and manipulated easily.
As mentioned earlier, we can use reflection to dynamically create an instance of any type,
bind the type to an existing object, or get the type from an existing object. Once this is
done appropriate method can be invoked, access the fields and properties. This can be
done by specifying the Type of object or by specifying both assembly and Type of the
object that needs to be created. By this the new object created acts like any other object and
associated methods, fields and properties can be easily accessed. With reflection we can
also find out about various methods associated with newly created object and how to use
these object. To find out the attributes and methods associated with an object we can use
the abstract class MemberInfo, this class is available under the namespace
System.Reflection.
Understanding Constructors in C#
Constructors are used for initializing the members of a class whenever an object is
created with the default values for initialization.
If a class is not defined with the constructor then the CLR (Common Language Runtime) will
provide an implicit constructor which is called as Default Constructor.
A class can have any number of constructors provided they vary with the number of
arguments that are passed, which is they should have different signatures.
If a class is defined with static and Non-static constructors then the privilege will
be given to the Non-static constructors.
Types of Constructors
i) Static : Used for initializing only the static members of the class. These will be
invoked for the very first time the class is being loaded on the memory. They cannot
accept any arguments. Static Constructors cannot have any access modifiers.
Syntax ---Static ClassName()
{
//Initialization statements;
}
ii) Non-Static : are used for initializing the Non-Static and Static members of a class.
These will be invoked everytime a new object is defined for a class.