Vtu 7TH Sem Cse/ise C# Programming & .Net Notes 10cs761/10is761
Vtu 7TH Sem Cse/ise C# Programming & .Net Notes 10cs761/10is761
NET
Subject Code: 10IS761/10CS761
Hours/Week : 04
Total Hours : 52
I.A. Marks : 25
Exam Hours: 03
Exam Marks: 100
PART A
UNIT 1
6 Hours
The Philosophy of .NET: Understanding the Previous State of Affairs, The.NET Solution, The Building Block of
the .NET Platform (CLR,CTS, and CLS), The Role of the .NET Base Class Libraries, What C# Brings to the Table,
An Overview of .NET Binaries (aka Assemblies), the Role of the Common Intermediate Language, The Role of
.NET Type Metadata, The Role of the assembly Manifast, Compiling CIL to Platform Specific Instructions,
Understanding the Common Type System, Intrinsic CTS Data Types, Understanding the Common Languages
Specification, Understanding the Common Language Runtime A tour of the .NET Namespaces, Increasing Your
Namespace Nomenclature, Deploying the .NET Runtime.
UNIT 2
6 Hours
Building C# Applications: The Role of the Command Line Complier (csc.exe), Building C# Application using
csc.exe Working with csc.exe Response Files, Generating Bug Reports, Remaining g C# Complier Options, The
Command Line Debugger (cordbg.exe) Using the, Visual studio .NET IDE, Other Key Aspects of the VS.NET IDE,
C# Preprocessor: Directives, an Interesting Aside: The System. Environment Class
UNIT 3
8 Hours
C# Language Fundamentals: The Anatomy of Basic C# Class, Creating objects: Constructor Basics, The
Composition of a C# Application, Default assignment and Variable Scope, The C# Member Initialisation Syntax,
Basic Input and Output with the Console Class, Understanding Value Types and Reference Types, The Master
Node: System, Object, The System Data Types (and C# Aliases), Converting Between Value Types and Reference
Types: Boxing and Unboxing, Defining Program Constants, C# Iteration Constructs, C# Controls Flow Constructs,
The Complete Set of C# Operators, Defining Custom Class Methods, Understating Static Methods, Methods
Parameter Modifies, Array Manipulation in C#, String Manipulation in C#, C# Enumerations, Defining Structures in
C#, Defining Custom Namespaces.
UNIT 4
6 Hours
Object- Oriented Programming with C#: Forms Defining of the C# Class, Definition the Default Public
Interface of a Type, Recapping the Pillars of OOP, The First Pillars: C#s Encapsulation Services, PseudoEncapsulation: Creating Read-Only Fields, The Second Pillar: C#s Inheritance Supports, keeping Family Secrets:
The Protected Keyword, Nested Type Definitions,The Third Pillar: C #s Polymorphic Support, Casting Between
.
PART B
UNIT 5
6 Hours
Exceptions and Object Lifetime: Ode to Errors, Bugs, and Exceptions, The Role of .NET Exception Handing, the
System. Exception Base Class, Throwing a Generic Exception, Catching Exception, CLR System Level
Exception(System. System Exception), Custom Application-Level Exception(System. System Exception), Handling
Multiple Exception, The Family Block, the Last Chance Exception Dynamically Identifying Application and
System Level Exception Debugging System Exception Using VS. NET, Understanding Object Lifetime, the CIT of
new, The Basics of Garbage Collection,, Finalization a Type, The Finalization Process, Building an Ad Hoc
Destruction Method, Garbage Collection Optimizations, The System. GC Type.
UNIT 6
6 Hours
Interfaces and Collections: Defining Interfaces Using C# Invoking Interface Members at the object Level,
Exercising the Shapes Hierarchy, Understanding Explicit Interface Implementation, Interfaces As Polymorphic
Agents, Building Interface Hierarchies, Implementing, Implementation, Interfaces Using VS .NET, understanding
the IConvertible Interface, Building a Custom Enumerator (IEnumerable
and Enumerator), Building Cloneable objects (ICloneable), Building Comparable Objects ( I Comparable ),
Exploring the system. Collections Namespace, Building a Custom Container (Retrofitting the Cars Type).
UNIT 7
8 Hours
Callback Interfaces, Delegates, and Events, Advanced Techniques: Understanding Callback Interfaces,
Understanding the .NET Delegate Type, Members of System. Multicast Delegate, The Simplest Possible Delegate
Example, , Building More a Elaborate Delegate Example, Understanding Asynchronous Delegates, Understanding
(and Using)Events.
The Advances Keywords of C#, A Catalog of C# Keywords Building a Custom Indexer, A Variation of the Cars
Indexer Internal Representation of Type Indexer . Using C# Indexer from VB .NET. Overloading operators, The
Internal Representation of Overloading Operators, interacting with Overload Operator from Overloaded- OperatorChallenged Languages, Creating Custom Conversion Routines, Defining Implicit Conversion Routines, The Internal
Representations of Customs Conversion Routines
UNIT 8
6 Hours
Understanding .NET Assembles: Problems with Classic COM Binaries, An Overview of .NET Assembly,
Building a Simple File Test Assembly, A C#. Client Application, A Visual Basic .NET Client Application, Cross
Language Inheritance, Exploring the CarLibrarys, Manifest, Exploring the CarLibrarys Types, Building the
Multifile Assembly, Using Assembly, Understanding Private Assemblies, Probing for Private Assemblies (The
Basics), Private A Assemblies XML Configurations Files, Probing for Private Assemblies ( The Details),
Understanding Shared Assembly, Understanding Shared Names, Building a Shared Assembly, Understanding
Delay Signing, Installing/Removing Shared Assembly, Using a Shared Assembly
Text Books:
1. Andrew Troelsen: Pro C# with .NET 3.0, Special Edition, Dream tech Press, India, 2007.
Chapters: 1 to 11 (up to pp.369)
2. E. Balagurusamy: Programming in C#, 5th Reprint, Tata McGraw Hill, 2004.
(Programming Examples 3.7, 3.10, 5.5, 6.1, 7.2, 7.4, 7.5, 7.6, 8.1, 8.2, 8.3, 8.5, 8.7, 8.8, 9.1, 9.2, 9.3, 9.4,
10.2, 10.4, 11.2, 11.4, 12.1, 12.4, 12.5, 12.6, 13.1, 13.2, 13.3, 13.6, 14.1, 14.2, 14.4, 15.2, 15.3, 16.1, 16.2,
16.3, 18.3, 18.5.18.6)
TABLE OF CONTENTS
UNIT 1: THE PHILOSOPHY OF .NET
1-13
14-25
26-59
60-73
74-90
91-106
It is literally true that you can succeed best and quickest by helping others to succeed.
1
Positive thinking will let you do everything better than negative thinking will.
2
The purpose of human life is to show compassion and the will to help others.
3
Achievement seems to be connected with action. Successful men and women keep moving.
They make mistakes, but they don't quit.
4
ROLE OF CIL
CIL is a language that sits above any particular platform-specific instruction set.
Regardless of which .NET-aware language we choose (like C#, VB.NET, VC++.NET etc), the
associated compiler produces CIL instructions.
Once the C# complier (csc.exe) compiles the source code file, we end up with a single file *.exe
assembly that contains a manifest, CIL instructions and metadata describing each aspect of the
program.
Benefits of CIL
Language Integration: Each .NET-aware language produces the same underlying-CIL. Therefore, all
.NET-aware languages are able to interact within a well-defined binary arena.
Since CIL is platform-agnostic, the .NET runtime is poised to become a platform-independent
architecture. Thus, .NET has the potential to allow us to develop an application in any language and
have it run on any platform.
Within the resulting "MetaInfo" window, we will find a description of the Add() method looking
something like the following:
Method #2
--------------------------------------------------------------------------MethodName: Add (06000002)
RVA: 000002064
ImplFlags: [IL] [Managed] (00000000)
hasThis
ReturnType: I4
2 Arguments
Argument #1: I4
Argument #2: I4
2 Parameters
(1) ParamToken: (08000001) Name: x flags: [none] (00000000)
(2) ParamToken: (08000002) Name: y flags: [none] (00000000)
In above metadata, we can see that Add() method, return type and method arguments have been
fully described by the C# compiler.
THE ROLE OF MANIFEST
Assemblies themselves are also described using metadata, which is termed as manifest.
The manifest contains information such as
name of assembly/ module
current version of the assembly
list of files in assembly
copyright information
list of all externally referenced assemblies required for proper execution
COMPILING CIL TO PLATFORM-SPECIFIC INSTRUCTIONS
Assemblies contain CIL instructions and metadata, rather than platform-specific instructions.
CIL must be compiled on-the-fly before use.
Jitter(Just-in-time compiler) is used to compile the CIL into meaningful CPU instructions.
The .NET runtime environment forces a JIT compiler for each CPU targeting the CLR, each of which is
optimized for the platform it is targeting.
Developers can write a single body of code that can be efficiently JIT-compiled and executed on
machines with different architectures. For example,
If we are building a .NET application that is to be deployed to a handheld device (such as a
Pocket PC), the corresponding Jitter is well equipped to run within a low-memory environment.
On the other hand, if we are deploying our assembly to a back-end server (where memory is
seldom an issue), the Jitter will be optimized to function in a high-memory environment
Jitter will cache the results in memory in a manner suited to the target OS. For example, if a call is
made to a method named PrintDocument(), the CIL instructions are compiled into platform-specific
instructions on the first invocation and retained in memory for later use. Therefore, the next time
PrintDocument() is called, there is no need to recompile the CIL.
A champion is someone who gets up when he can't.
6
Class
Characteristic
Is the class sealed
or not?
Does the class
implement any
interfaces?
Is the class abstract
or concrete?
What is the
visibility of this
class?
Meaning
Sealed classes cannot function as a base class to other classes.
An interface is a collection of abstract members that provide a
contract between the object and object-user. The CTS allows a
class to implement any number of interfaces.
Abstract classes cannot be directly created, but are intended to
define common behaviors for derived types. Concrete classes
can be created directly.
Each class must be configured with a visibility attribute.
Basically, this feature defines if the class may be used by
external assemblies, or only from within the defining assembly
(e.g., a private helper class).
Desire is the starting point of all achievement, not a hope, not a wish, but a keen pulsating desire which transcends
everything.
7
The secret of happiness is to count your blessings while others are adding up their troubles.
8
Given this rule, we can understand that the remaining rules of the CLS do not apply to the logic used
to build the inner workings of a .NET type.
The only aspects of a type that must match to the CLS are the member definitions themselves (i.e.,
naming conventions, parameters, and return types).
The implementation logic for a member may use any number of non-CLS techniques, as the outside
world wont know the difference.
To illustrate, the following Add() method is not CLS-compliant, as the parameters and return values
make use of unsigned data (which is not a requirement of the CLS):
public class Calc
{
// Exposed unsigned data is not CLS compliant!
public ulong Add(ulong x, ulong y)
{
return x + y;
}
}
Now, we have a match to the rules of the CLS, and can assured that all .NET languages are able to
invoke the Add() method.
Ensuring CLS compliance
C# does define a number of programming constructs that are not CLS-compliant. But, we can
instruct the C# compiler to check the code for CLS compliance using a single .NET attribute:
// Tell the C# compiler to check for CLS compliance.
[assembly: System.CLSCompliant(true)]
This statement must be placed outside the scope of any namespace. The [CLSCompliant] attribute
will instruct the C# compiler to check each and every line of code against the rules of the CLS. If any
CLS violations are discovered, we will receive a compiler error and a description of the offending code.
Successful people ask better questions, and as a result, they get better answers.
9
The poor, the unsuccessful, the unhappy, the unhealthy are the ones who use the word tomorrow the most.
10
In above code, each language is making use of Console class defined in the System namespace.
"System" namespace provides a core body of types that we will need to use as a .NET developers.
We cannot build any sort of functional C# application without making a reference to the "System"
namespace.
System" is the root namespace for numerous other .NET namespaces.
.NET NAMESPACES
System
In this, we find numerous low-level classes dealing with primitive types, mathematical
manipulations, garbage collection, exceptions and predefined attributes.
System.Collections
This defines a number of stock container objects (ArrayList, Queue, etc) as well as base types
and interfaces that allow us to build customized collections.
System.Data.OleDb
These are used for database manipulation.
System.Diagnostics
In this, we find numerous types that can be used by any .NET-aware language to
programmatically debug and trace our source code.
System.Drawing System.Drawing.Printing
In this, we find numerous types wrapping GDI+ primitives such as bitmaps, fonts, icons,
printing support, and advanced graphical rendering support.
System.IO
This includes file IO and buffering.
System.Net
This contains types related to network programming (requests/responses, sockets, end points)
System.Security
In this, we find numerous types dealing with permissions, cryptography and so on.
System.Xml
This contains numerous types that represent core XML primitives and types used to interact
with XML data.
System.Threading
This deals with threading issues. In this, we will find types such as Mutex, Thread and Timeout.
There's always a way - if you're committed.
11
Once we specify a namespace, we can create instances of the types they contain. For example, if we
are interested in creating an instance of the Bitmap class, we can write:
using System;
using System.Drawing;
class MyApp
{
public void DisplayLogo()
{
// create a 20x20 pixel bitmap.
Bitmap bm = new Bitmap(20, 20);
...
}
}
As this application is referencing System.Drawing, the compiler is able to resolve the Bitmap class as
a member of this namespace. If we do not specify the System.Drawing namespace, we will get a
compiler error. However, we can declare variables using a fully qualified name as well:
using System;
class MyApp
{
public void DisplayLogo()
{
// Using fully qualified name.
System.Drawing.Bitmap bm =new
System.Drawing.Bitmap(20, 20);
...
}
}
Following Techniques can be used to learn more about the .NET Libraries
.NET SDL online documentation
The ildasm.exe utility
The class viewer web application.
The wincv.exe desktop application.
Deploying the .NET Runtime
The .NET assemblies can be executed only on a machine that has the .NET Framework installed.
But, we can not copy and run a .NET application in a computer in which .NET is not installed.
However, if we deploy an assembly to a computer that does not have .NET installed, it will fail to run.
For this reason, Microsoft provides a setup package named dotnetfx.exe that can be freely shipped and
installed along with our custom software.
Once dotnetfx.exe is installed, the target machine will now contain the .NET base class libraries, .NET
runtime (mscoree.dll), and additional .NET infrastructure (such as the GAC, Global Assembly Cashe).
Knowledge is power. The more knowledge, expertise, and connections you have, the easier it is for you to make a profit
at the game of your choice.
12
C# Keyword
byte
sbyte
short
int
long
ushort
float
double
object
char
string
decimal
bool
Managed Extensions
for C++ Keyword
unsigned char
signed char
short
int or long
__int64
unsigned short
Float
Double
Object^
wchar_t
String^
Decimal
Bool
EXERCISES
1) Briefly discuss state of affairs that eventually led to .NET platform. (8)
2) Explain .NET solution. (4)
3) What are the key features of C#? (4)
4) With a neat diagram, explain basic building block of .NET framework. (8)
5) What do you mean by Base class library? Explain. (2)
6) Explain the concept of .NET binaries. (6)
7) Bring out important differences b/w single and multifile assemblies. (4)
8) Explain the role of CIL and the benefits of CIL. (4)
9) Explain the role of JIT compiler. (6)
10) What are basic CTS data types? Explain. (8)
11) Explain common type system in detail. (6)
12) Explain with a neat diagram, the workflow that takes place between your source
code, a given .NET complier and the .NET execution engine. (8)
13) What are namespaces? List and explain the purpose of at least five namespaces. (6)
Other people's opinion of you does not have to become your reality.
13
Once finished writing the code in some editor, save the file as TestApp.cs
To compile & run the program, use the following command-set:
Output:
C:\CSharpTestApp> csc TestApp.cs
C:\CSharpTestApp> TestApp.exe
Testing 1 2 3
testapp.cs
hellomsg.cs
As an alternative, we can make use of the wildcard character(*) to inform the compiler to include all
*.cs files contained in the project-directory.
In this case, we have to specify the name of the output-file(/out) to directly control the name of the
resulting assembly:
csc
/r:System.Windows.Forms.dll
/out:TestApp.exe
*.cs
/r:System.Windows.Forms.dll;
System.Drawing.dll
*.cs
Save this response-file in the same directory as the source-files to be compiled. Now, we can build
our entire application as follows:
csc @TestApp.rsp
Any flags listed explicitly on the command-line will be overridden by the options in a given responsefile. Thus, if we use the statement,
csc /out:Foo.exe @TestApp.rsp
The name of the assembly will still be TestApp.exe(rather than Foo.exe),given the /out:TestApp.exe
flag listed in the TestApp.rsp response-file.
Determination gives you the resolve to keep going in spite of the roadblocks that lay before you.
15
/out:Test.exe
*.cs
If we wish to disable the automatic reading of csc.rsp, we can specify the /noconfig option:
csc
@Test.rsp
/noconfig
/bugreport:
bugs.txt
*.cs
We can enter any corrective information for possible errors in the program, which will be saved to the
specified file (i.e. bugs.txt).
Consider the following code with an error (bug):
public static void Main()
{
HelloMessage h=new HelloMessage();
h.Speak()
// error occurs because ; is missing
}
When we compile this file using /bugreport flag, the error message will be displayed and corrective
action is expected as shown
Test.cs (23, 11): Error CS1002: ; expected
----------------Please describe the compiler problem: _
The hardest thing to learn in life is which bridge to cross and which to burn.
16
With better awareness come better choices. And with better choices, youll see better results
17
The above command-set generates a new file named testapp.pdb. If we do not have an associated
*.pdb file, it is still possible to make use of cordbg.exe, however, we will not be able to view our C#
source code during the process.
Once we have a valid *.pdb file, open a session with cordbg.exe by specifying our assembly as a
command line argument(the *.pdb file will be loaded automatically):
cordbg.exe testapp.exe
At this point, we are in debugging mode, and may apply any number of cordbg.exe flags at the
(cordbg)" command prompt.
CORE PROJECT WORKSPACE TYPES IN VS.NET IDE
Windows Application
This represents a windows forms application.
Class Library
This allows building a single file assembly.
Windows Control Library
This allows building a single file assembly that contains custom windows forms controls.
ASP.NET Web Application
This is selected when we want to build an ASP.NET web application.
ASP.NET Web Service
This allows to build a .NET web services. A web service is a block of code, reachable using HTTP
requests.
Web Control Library
This allows to build customized web controls. These GUI widgets are responsible for emitting
HTML to a requesting browser.
Windows Services
This allows to build NT/2000 services. These are background worker applications that are
launched during the OS boot process.
Refuge to be average. Stand for what's best. Commit to being breathtakingly great in all you do.
18
}
#endregion
The richest person in the world isn't the person who has the most but the one who needs the least.
24
Note that the line number appeared as 300, though the actual line was 7.
THE SYSTEM.ENVIRONMENT CLASS
This class can be used to obtain a number of details regarding the context of the OS hosting the
application using various static members. For example, consider the following code:
using System;
class PlatformSpy
{
public static int Main(strng[] args)
{
Console.WriteLine("Current OS:{0}",Environment.OSVersion);
Console.WriteLine("Current directory :{0}",Environment.CurrentDirectory);
string[] drives=Environment.GetLogicalDrives();
for(int i=0;i<drives.Length;i++)
Console.WriteLine("Drive {0} : {1}",i,drives[i]);
The Output will be Current OS: Microsoft Windows NT 5.1.2600 Service Pack 3
Current directory: C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0
Drive 0: A:\
Drive 1: C:\
Drive 2: D:\
Drive 3: E:\
Drive 4: F:\
Current version of .NET: 2.0.50727.3082
EXERCISES:
1. Explain the role of csc.exe. (6)
2. List and explain the basic output options available with C# complier. (6)
3. Explain the following, with respect to compilation of C# program: (6)
i) referencing external assemblies
ii) compiling multiple source files
4. What are response files? Explain with an example. (4)
5. How do you generate bug reports? Illustrate with an example.
(6)
6. What are C# preprocessor directives? Explain. (6)
7. Explain the following aspects of VS.NET IDE: (8)
i) Solution Explorer
ii) Running and debugging
iii) Documenting code via XML
Life really is a fragile gift, and it needs to be lived right now. Neither of us knows how many tomorrows we have left.
25
All the things you dont like about your life are actually your best friends & greatest teachers because they help you
get to your destination--your ideal life.
26
return 0;
Output:
Here, we are checking to see if the array of strings contains some number of items using Length
property of System.Array.
If we have at least one member in array, we loop over each item & print contents to output window.
Using "foreach" keyword
Consider the following code:
using System;
class HelloClass
{
public static int Main(string[] args)
{
Console.WriteLine(" Command line arguments \n ");
foreach(string s in args)
Console.WriteLine("Argument {0}:",s);
}
}
foreach loop can used to iterate over all items within an array, without the need to test for the
arrays upper limit.
Using GetCommandLineArgs() method of System.Environment type
Consider the following code:
using System;
class HelloClass
{
public static int Main(string[] args)
{
string[] theArgs=Environment.GetCommandLineArgs();
Console.WriteLine("path is :{0}",theArgs[0]);
Console.WriteLine(" Command line arguments \n ");
for(int i=1;i<theArgs.Length;i++)
Console.WriteLine("Arguments :{0}",theArgs)
}
}
Output:
We can also access command line arguments using the GetCommandLineArgs() method of the
System.Environment type.
First index identifies current directory containing the program itself,
while remaining elements in the array contain the individual command-line arguments.
We have phenomenal power within us, we've just lost connection to it. Part of the reason for this is fear.
27
return 0;
Shift from trying to control your life to becoming curious about your life.
28
//assigned to 0
//assigned to 0.0
//assigned to 0"
//assigned to false
//assigned to null
//assigned to <undefined value>
Member
BackgroundColor
ForegroundColor
BufferHeight/Width
Clear()
Title
WindowHeight
Meaning
These properties set background/foreground colors for current output. They
may be assigned any member of the ConsoleColor enumeration.
These properties control the height/width of the consoles buffer area.
This method clears the buffer and console display area.
This property sets the title of the current console.
This property control dimensions of console in relation to the buffer
Output:
Integer is: 77
Float is :7.62
String is :hello
The first parameter to WriteLine() represents a format-string that contains optional placeholders
designated by {0},{1},{2}.
The remaining parameters to WriteLine() are the values to be inserted into the respective
placeholders.
WriteLine() has been overloaded to allow us to specify placeholder values as an array of objects. For
example, consider the following lines of code.
object[] stuff={"hello",20.9,"there","1986"};
Console.WriteLine("the stuff: {0},{1},{2},{3}",stuff);
A given placeholder can be repeated within a given string. For example, consider the following line of
code.
Console.WriteLine("{0}number{0}number{0}",9);
//prints $99,987.99
//prints 00009.9987
//prints 9.9987E+004
//prints 100000.000
//prints 99,987.00
//prints 1869F
Our lives are nothing more than a series of moment --- if you miss the moments, you miss your life.
30
class Foo
{
public int x,y;
}
class ValRef
{
public static int Main(string[] args)
{
Foo f1=new Foo();
f1.x=100;
f1.y=100;
Console.WriteLine(assigning f2 to f1);
Foo f2=f1;
Console.WriteLine(f1.x={0},f1.x);
Console.WriteLine(f1.y={0},f1.y);
Console.WriteLine(f2.y={0},f2.y);
Console.WriteLine(f2.y={0},f2.y);
Console.WriteLine(changing f2.x to 900);
f2.x=900;
Console.WriteLine(here are the Xs again);
Console.WriteLine(f2.x={0},f2.x);
Console.WriteLine(f1.x={0},f1.x);
return 0;
}
}
Output:
assigning f2 to f1
f1.x=100
f1.y=100
f2.x=100
f2.y=100
changing f2.x to 900
here are the Xs again
f2.x=900
f1.x=900
VALUE TYPES
Allocated on the stack
Variables die when they fall out of the defining scope
REFERENCE TYPES
Allocated on the managed heap
Variables die when the managed heap is garbage
collected
Variables are pointing to the memory occupied by the
allocated instance
Variables are passed by reference
Variables can derive from any other type as long as
that type is not "sealed"
Reference type is not sealed, so it may function as a
base to other types.
Reference types finalized before garbage collection
occurs
Output:
making InnerRef type and setting structData to 666
assigning valWithRef2 to valWithRef
changing all values of valWithRef2
values after change
valWithRef.refType.x is I AM NEW
valWithRef2.refType.x is I AM NEW
valWithRef.structData is 666
valWithRef2.structData is 777
When a value-type contains other reference-types, assignment results in a copy of the references. In
this way, we have 2 independent structures, each of which contains a reference pointing to the same
object in memory i.e. shallow copy.
When we want to perform a deep copy (where the state of internal references is fully copied into a
new object), we need to implement the ICloneable interface.
// unboxing successful
// InvalidCastException
Generally, there will few situations in which we need boxing and/or unboxing.
In most of the situations, C# compiler will automatically boxes the variables. For example, if we pass
a value type data to a function having reference type object as a parameter, then automatic boxing
takes place.
Consider the following program:
using System;
class Test
{
public static void MyFunc(object ob)
{
Console.WriteLine(ob.GetType());
Console.WriteLine(ob.ToString());
Console.WriteLine(((int)ob).GetTypeCode());
}
Output:
//explicit unboxing
//automatic boxing
System.Int32
20
Int32
When we pass custom (user defined) structures/enumerations into a method taking generic
System.Obejct parameter, we need to unbox the parameter to interact with the specific members of
the structure/enumeration.
Success is nothing more than living your life according to your own truth & on your own terms
33
Normally methods will take parameter. While calling a method, parameters can be passed in different
ways.
C# provides some parameter modifiers as shown:
Parameter
Meaning
Modifier
(none)
If a parameter is not attached with any modifier, then parameters value is
passed to the method. This is the default way of passing parameter. (call-byvalue)
out
The output parameters are assigned by the called-method.
ref
The value is initially assigned by the caller, and may be optionally reassigned by
the called-method
params
This can be used to send variable number of arguments as a single parameter.
Any method can have only one params modifier and it should be the last
parameter for the method.
THE DEFAULT PARAMETER PASSING BEHAVIOR
By default, the parameters are passed to a method by-value.
If we do not mark an argument with a parameter-centric modifier, a copy of the data is passed into
the method.
So, the changes made for parameters within a method will not affect the actual parameters of the
calling method.
Consider the following program:
using System;
class Test
{
public static void swap(int x, int y)
{
int temp=x;
x=y;
y=temp;
}
Output:
Before: x=5, y=20
After : x=5, y=20
Our lives aren't run by good or bad luck, but by an intelligent process designed to help us evolve into our best selves.
34
Output:
z=25
Useful purpose of out: This allows the caller to obtain multiple return values from a single methodinvocation.
Consider the following program:
using System;
class Test
{
public static void MyFun(out int x, out string y, out bool z)
{
x=5;
y="Hello, how are you?";
z=true;
}
public static void Main()
{
int a;
string str;
bool b;
MyFun(out a, out str, out b);
Console.WriteLine("integer={0} ", a);
Console.WriteLine("string={0}", str);
Console.WriteLine("boolean={0} ", b);
}
Output:
integer=5,
string=Hello, how are you?
boolean=true
The deepest personal defeat suffered by human beings is constituted by the difference between what one was capable
of becoming & what one has in fact become
35
Output:
Before: hello
After: HELLO
All the dots in our lives are connected, and everything that happens to us happens for a reason.
36
Output:
5
MyFun(a);
MyFun(p, q);
10
15
25
102
From the above example, we can observe that for params parameter, we can pass an array or
individual elements.
We can use params even when the parameters to be passed are of different types.
Consider the following program:
using System;
class Test
{
public static void MyFun(params object[] arr)
{
for(int i=0; i<arr.Length; i++)
{
if(arr[i] is Int32)
Console.WriteLine("{0} is an integer", arr[i]);
else if(arr[i] is string)
Console.WriteLine("{0} is a string", arr[i]);
else if(arr[i] is bool)
Console.WriteLine("{0} is a boolean",arr[i]);
}
}
public static void Main()
{
int x=5;
string s="hello";
bool b=true;
MyFun(b, x, s);
Output:
True is a Boolean
5 is an integer
hello is a string
Output:
Raja
Raja
John
33
66
22
Rule1: If a reference type is passed by value, the called-method may change the values of the
objects data but may not change the object it is referencing.
Rule 2: If a reference type is passed by reference, the called-method may change the values of the
objects data and also the object it is referencing.
EXERCISES
1) Explain the anatomy of a Basic C# Class. (6)
2) Explain the 3 methods of processing command line parameters. (6)
3) With example, explain objects & constructors. (6)
4) With example, explain default assignments and variable scope. (4)
5) What are basic input & output functions in Console class? Explain with example. (6)
6) Write a note on formatting textual input. (4)
7) List out & explain the string formatting flags with example. (4)
8) Explain value types and reference types with example for each. (6)
9) Compare value types vs. reference types (4)
10) With example, explain value types containing reference types. (6)
11) What is boxing and unboxing? Explain with example. (6)
12) Explain various method parameter modifiers with example for each. (8)
13) With example, explain passing reference types by value and reference. (6)
Every single person on the planet has a portion of ourselves that we hide from the world.
38
Instance Method
of Object Class
Equals()
GetHashCode()
GetType()
ToString()
Finalize()
MemberwiseClone()
Meaning
By default, this method returns true only if the items being compared
refer to the exact same item in memory.
Thus, Equals() is used to compare object references, not the state of
the object.
Typically, this method can be overridden to return true only if the
objects being compared have the same internal state values.
This method returns an integer that identifies a specific object in
memory.
This method returns a System.Type object that fully describes the
details of the current item.
This method returns a string representation of a given object, using
the namespace.typename format (i.e., fully qualified name).
If the type has not been defined within a namespace, typename alone
is returned.
Typically, this method can be overridden by a subclass to return a
tokenized string of name/value pairs
This method is invoked by the .NET runtime when an object is to be
removed from the heap (during garbage collection).
This method is used to return a new object that is a member-bymember copy of the current object.
Thus, if the object contains references to other objects, the references
to these types are copied (i.e., it achieves a shallow copy).
If the object contains value types, full copies of the values are
achieved (i.e., it achieves a deep copy).
No matter how beautiful your outer world looks, it's what's on the inside that's important.
39
Output:
***** Working with Object *****
p1.ToString: Person
p1.GetHashCode: 58225482
p1's base class: System.Object
p1, p2 and o are same objects!
In the above program, the default implementation of ToString() simply returns the fully qualified
name of the type.
GetType() retrieves a System.Type object, which defines a property named.
Here, new Person object p1 is referencing memory in the heap.
We are assigning p2 to p1. Therefore, p1 and p2 are both pointing to the same object in memory.
Similarly the variable o (of type object) also refers to the same memory. (Thus, when we compare
p1, p2 and o, it says that all are same).
Silence is nature's sweet restorer, opening up a space in our lives to connect with our best selves --it's a tonic that heals us & caresses our souls.
40
Output:
p1 is [Name=Ram SSN=11-12 Age=25]
In the above example, we have overridden ToString() method to display the contents of the object in
the form of tuple.
The System.Text.StringBuilder is class which allows access to the buffer of character data and it is a
more efficient alternative to C# string concatenation.
}
return false;
Output:
if(p2.Equals(p4))
//compares based on content, not on reference
Console.WriteLine("p4 and p2 are same");
else
Console.WriteLine("p4 and p2 are not same");
While overriding the Equals() method, first we are checking whether the passed object is of class
Person or not.
Also, we need to check whether the object has been allocated memory or it is having null. Note
that Equals() method takes the parameter of type object. Thus, we need to type-cast it to Person type
before using it.
When we override Equals(), we need to override GetHashCode() too.
Have big-time fun as you chase & catch your most cherished dreams.
42
void Main()
=
=
=
=
if(p1.Equals(p3))
Console.WriteLine("p1 and p3 are same");
else
Console.WriteLine("p1 and p3 are not same");
if(p1.GetHashCode()==p3.GetHashCode())
//comparison based on SSN
Console.WriteLine("p1 and p3 are same");
else
Console.WriteLine("p1 and p3 are not same");
Output:
A powerful dream gives you hope. Focus will flood your days because you'll know exactly what you've been placed on the
planet to do.
43
}
Output:
0 1 2 3
dog
cat
bird
Apart from iterating over simple arrays, foreach loop can be used to iterate over system supplied or
user-defined collections.
WHILE AND DO/WHILE LOOP
When we dont know the exact number of times a set of statements to be executed, we will go for
while loop. That is, a set of statements will be executed till a condition remains true. For example:
class Program
{
static void Main()
{
// Continue in while-loop until index is equal to 3.
int i = 0;
while (i < 2)
{
Console.Write("C# Language ");
// Write the index to the screen.
Console.WriteLine(i);
// Increment the variable.
i++;
}
}
}
Output
C# Language 0
C# Language 1
Some times, we need a set of statements to be executed at least once, irrespective of the condition.
Then we can go for do/while loop. For example:
string opt;
do
{
Console.Write(Do you want to continue?(Yes/No): );
opt=Console.ReadLine();
}while(opt!=Yes);
A life well lived is all about reaching for your highest & your best.
44
Meaning
To check equality of two operands
Not equal to
Less than
Greater than
Less than or equal to
Greater than or equal to
Meaning
Logical AND
Logical OR
Logical NOT
For example:
class Selections
{
public static int Main(string[] args)
{
Console.WriteLine("1 C#\n 2 Managed C++\n 3 VB.NET");
Console.WriteLine("please enter your implementation language");
int n=Console.ReadLine();
switch(n)
{
case 1: Console.WriteLine("good choice C# is all about managed code");
break;
case 2: Console.WriteLine("let me guess, maintaining a legacy system?");
break;
case 3: Console.WriteLine("VB.NET It is not just for kids anymore");
break;
default: Console.WriteLine("well good luck with that");
break;
}
return 0;
}
}
CLS
Compliant?
No
Yes
Yes
No
Yes
No
Yes
Yes
Yes
System Type
System.SByte
System.Byte
System.Int16
System.UInt16
System.Int32
System.UInt32
System.Int64
System.Char
System.Single
bool
decimal
string
Yes
Yes
Yes
System.Boolean
System.Decimal
System.String
object
Yes
System.Object
Range
-128 to 127
0 to 255
-216 to 216-1
0 to 232-1
-232 to 232-1
0 to 264-1
-264 to 264-1
U10000 to U1ffff
1.5 x 10-45 to
3.4 x 1038
True or False
1 to 1028
Limited by system
memory
Anything derive from
object
Meaning
Signed 8-bit number
Unsigned 8-bit number
Signed 16-bit number
Unsigned 16-bit number
Signed 32-bit number
Unsigned 32-bit number
Signed 64-bit number
A Single 16-bit Unicode character
32-bit floating point number
Represents truth or falsity
96-bit signed number
Represents a set of Unicode
characters
The base class of all types in the
.NET universe.
From this table, we can see that all the types are ultimately derived from System.Object.
Since the data types like int are simply shorthand notations for the corresponding system type (like
System.Int32), the following statements are valid
Console.WriteLine(25.GetHashCode());
Console.WriteLine(32.GetType().BaseType()); etc.
We can see that, though C# defines a number of data types, only a subset of the whole set of data
types are compliant with the rules of CLS.
So, while building user-defined types (like class, structures), we should use only CLS-compliant
types.
And also, we should avoid using unsigned types as public member of user-defined type.
By doing this, the user-defined type (class, enumeration, structure etc) can be understood by any
language in .NET framework.
An extraordinary life contains both success & significance. The essence of life is balance.
46
//65535
//0
//30000
//System.UInt16
ushort b=12000;
Console.WriteLine("Max value for ushort: {0}", ushort.MaxValue);
Console.WriteLine("Min value for ushort: {0}", ushort.MinValue);
Console.WriteLine("value of ushort: {0}", b);
Console.WriteLine("The type is: {0}", b.GetType().ToString());
}
//65535
//0
//12000
//System.UInt16
MEMBERS OF SYSTEM.BOOLEAN
The only valid assignment a bool can take is from the set {true | false}.
We cannot assign make-shift values (e.g. 1 0 -1) to a bool.
System.Boolean
does
not
support
a
MinValue/MaxValue
property-set
but
rather
TrueString/FalseString.
MEMBERS OF SYSTEM.CHAR
All the .NET-aware languages map textual data into the same underlying types viz System.String and
System.Char, both are Unicode.
The System.Char type provides several methods as shown in the following example:
using System;
class Test
{
public static void Main()
{
bool b1=true;
bool b2=false;
Console.WriteLine("{0}", bool.FalseString);
Console.WriteLine("{0}", bool.TrueString);
Console.WriteLine("{0}, {1}", b1, b2);
Console.WriteLine("{0}", char.IsDigit('P'));
Console.WriteLine("{0}", char.IsDigit('9'));
Console.WriteLine("{0}", char.IsLetter("10", 1));
Console.WriteLine("{0}", char.IsLetter("1a", 1));
Console.WriteLine("{0}", char.IsLetter('p'));
Console.WriteLine("{0}", char.IsWhiteSpace("Hello World", 5));
Console.WriteLine("{0}", char.IsWhiteSpace("Hello World", 6));
Console.WriteLine("{0}", char.IsLetterOrDigit('?'));
Console.WriteLine("{0}", char.IsPunctuation('!'));
Console.WriteLine("{0}", char.IsPunctuation(','));
}
}
//False
//True
//True, False
//False
//True
//False
//True
//True
//True
//False
//False
//True
//True
Do good things for yourself & others in your life, and good things are certain to flow back to you.
47
Output:
my integer constant=5
my string constant= i am a constant
local constant= i am a rock,i am an island
When you make better choices, you are certain to experience better results.
48
//1
//2
//3
In .NET, the members of array are automatically set to their respective default value. For example, in
the statement,
int[ ] a= new int[10];
all the elements of a are set to 0. Similarly, string array elements are set to null and so on.
ARRAY AS PARAMETERS AND RETURN VALUES
Array can be passed as parameter to a method and also can be returned from a method.
Consider the following program:
using System;
class Test
{
public static void disp(int[ ] arr)
//taking array as parameter
{
for(int i=0;i<arr.Length;i++)
Console.WriteLine("{0} ", arr[i]);
}
public static string[ ] MyFun()
//returning an array
{
string[ ] str={"Hello", "World"};
return str;
}
public static void Main()
{
int[ ] p=new int[ ]{20, 54, 12, -56};
disp(p);
Output:
20
54
string[ ] strs=MyFun();
foreach(string s in strs)
Console.WriteLine(s);
12
-56
Hello
World
}
Output:
0
0
0
0
0
0
0
1
2
3
4
5
// Print (6 * 6) array.
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 6; j++)
Console.Write(myMatrix[i, j] + "\t");
Console.WriteLine();
}
0
2
4
6
8
10
0
3
6
9
12
15
0
4
8
12
16
20
0
5
10
15
20
25
}
Output:
Element(0): 1 3 5 7 9
Element(1): 2 4 6 8
Goals breathe life & energy into your days. Most people don't get up early because they have no reason to.
51
Output:
32
are:
0
67
12
12
Console.WriteLine(s1.Replace('a',' '));
Output:
Different strings
s3=This is a stringThis is another string
Char 0 is T
Char 1 is h
Char 4 is
Char 5 is I
Char 8 is a
Char 9 is
Char 12 is r
Char 13 is I
Contains 'is'?: True
This is string
Char 2 is i
Char 6 is s
Char 10 is s
Char 14 is n
Char 3 is s
Char 7 is
Char 11 is t
Char 15 is g
The secret of passion is purpose. Once you find your calling, your heart will begin to sing, and you'll have more passion,
power and inner peace than you ever could have imagined.
53
Output:
I said, "Hi"
C:\Notes\DotNet\Chapter3.doc
C:\Notes\DotNet\Chapter3.doc
USING SYSTEM.TEXT.STRINGBUILDER
The value of a string cannot be modified once established. i.e. strings are immutable.
The methods like Replace() may seems to change the content of the string, but actually, those
methods just output a copy of the string and the original string remains the same. For example:
string s1=hello;
Console.WriteLine(s1={0}, s1);
string s2=s1.ToUpper();
Console.WriteLine(s2={0}, s2);
Console.WriteLine(s1={0}, s1);
//hello
//HELLO
//hello
Thus, whenever we want to modify a string, we should have a new string to store the modified
version. That is, every time we have to work on a copy of the string, but not the original.
To avoid this in-efficiency,C# provides class called StringBuilder present in namespace System.Text.
Any modification on an instance of StringBuilder will affect the underlying buffer itself.
Consider the following program:
using System.Text;
class Test
{
public static void Main()
{
StringBuilder s1= new StringBuilder("hello");
s1.Append(" world");
Console.WriteLine("{0}",s1);
string s2=s1.ToString().ToUpper();
Console.WriteLine("{0}",s2);
}
}
Output:
hello world
HELLO WORLD
One of our biggest regrets on our deathbeds is that we were not reflective enough.
54
//0
//1
//2
//3
In enumeration, the value for first symbolic name is automatically initialized to 0 and second to 1 etc.
If we want to give any specific value, we can use
enum M_Status
{
Married =125,
Widowed,
Unmarried,
Divorced
}
//126
//127
//128
or
enum M_Status
{
Married =125,
Widowed=0,
Unmarried=23,
Divorced=12
}
By default, the storage type used for each item of enumeration is System.Int32. We can change it, if
we wish
enum M_Status: byte
{
Married =125,
Widowed=0,
Unmarried=23,
Divorced=12
}
if(p1==M_Status.Married)
Console.WriteLine("p1 is married");
// p1 is married
if(p2==M_Status.Divorced)
Console.WriteLine("p2 is {0}", M_Status.Divorced);
//p2 is Divorced
Output:
M_Status p2=M_Status.Married;
if(p1<p2)
Console.WriteLine(p1 has less value than p2);
else
Console.WriteLine(p1 has more value than p2);
System.Int32
This enum has 4 members
String name: Married
String name: Widowed
String name: Unmarried
String name: Divorced
Widowed is defined
p1 is Divorced
p1 has more value than p2
int: (0)
int: (1)
int: (2)
int: (3)
hex:
hex:
hex:
hex:
(00000000)
(00000001)
(00000002)
(00000003)
Its human nature not to appreciate all we have until it's lost.
56
}
class Test
{
object ob=e;
MyFun(ob);
//boxing
Output:
Name =Raja, Age =25
After boxing and un-boxing:
Name =Raja, Age =25
Small choices lead to giant consequences-- over time. There's no such thing as an unimportant day.
57
Now, the namespace Vehicle acts as a container for all these classes. If we want to create an object
of any of these classes in any other application, we can simply write
using System;
using Vehicle;
//note this
class Test
{
public static void Main()
{
Car c=new Car();
------------}
}
When we include the namespaces MyVehicle and Vehicle, and try to create an object of Car class, we
will get an error.
To avoid this, we will use dot operator for combining namespace name & class name. For example:
using System;
using Vehicle;
using MyVehicle;
class Test
{
public static void Main()
{
Car c=new Car();
//Error!!! name conflict
Vehicle.Car c1=new Vehicle.Car();
MyVehicle.Car c2=new MyVehicle.Car();
--------}
}
Reading is one of the best disciplines to stay on your game & at your highest.
58
NESTED NAMESPACES
We can nest one namespace within the other also. For example
namespace Vehicle
{
namespace MyVehicle
{
--------}
}
Or
namespace Vehicle.MyVehicle
{
------}
EXERCISES
1) What is System.Object? Explain the instance methods of Object Class. (6)
2) Explain the default behavior of System.Object with example. (6)
3) How do you override ToString()of System.Object? Explain with example. (6)
4) How do you override Equals()of System.Object? Explain with example. (6)
5) Explain 4 iteration constructs with example for each. (8)
6) Explain 2 control flow constructs with example. (6)
7) Draw a diagram to depict the hierarchy of System types and explain. (6)
8) List out & explain various method access modifiers. (4)
9) Explain the static method and static data with example for each. (6)
10) Explain 2 types of multi-dimensional arrays with example for each. (8)
11) List out & explain core members of System.Array class. (4)
12) List out & explain core members of System.String class. (4)
13) Explain the features of StringBuilder class with example. (6)
14) Explain escape characters and verbatim strings with example. (4)
15) List out & explain core members of System.Enum class. (4)
16) Explain (un)boxing custom structures with example. (4)
17) Explain the following with reference to namespace: (8)
i) Defining custom namespaces
ii) Resolving name clashes across namespaces
iii) Defining namespace aliases
METHOD OVERLOADING
The method is said to be overloaded if a class has a set of identically named-members that differ by
the number/type/order of parameters.
Eg:
class Employee
{
public Employee() {. . .}
public Employee(string fullName, int empID)
{. . .}
}
// generate
//compile error
Discovering a powerful dream that you can live your life by, will give you immense power, drive and energy.
60
The second custom constructor requires a single parameter. However, to full construct a new
System.Object is the topmost-node in any .NET hierarchy. Here, the "shape" class extends "Object".
"Shape" defines some number of properties, fields, methods and events that are common to all shapes
(Figure 4-3).
The "Hexagon" class extends "Shape" and inherits the core-functionality defined by "Shape" and
"Object." "Hexagon" also defines additional hexagon-related details of its own.
We can read this diagram is "A hexagon is- shape that is an object". When we have classes-related
by this form of inheritance, we establish "is-a" relationships between types.
"has-a" relationship is a form of reuse but is not used to establish base/subclass relationships.
Rather, a given class (e.g. Car) can define a member-variable of another class(eg Radio) and expose
part or all of its functionality to the outside world (Figure 4-4).
For eg, if we are modeling an automobile, we might wish to express the idea that a car "has-a" radio.
Here, we have 2 independent classes working together, where the containing-class (e.g. Car) creates
2) Adhoc polymorphism allows objects that are not related by classical inheritance to be
treated in a similar manner, provided that every object has a method of the exact same
signature (Figure 4-6).
Language that support adhoc polymorphism employ a technique called late-binding to discover
at runtime the underlying type of a given object. Based on this discovery, the correct method is
invoked.
In figure, there is no common base class among the CCircle, CHexagon and CRectangle
classes. However, each class supports a identical Draw() method.
Life is a skill. And like any other skill, once you know the ground rules & make the time to practice, you can get better.
64
The class DBReader has encapsulated the inner details of locating, loading, manipulating and closing
data file. But, the object user need not worry about all these.
Closely related to notion of encapsulation is data hiding. We do this by making data members as
private.
The private data can be modified only through the public member functions of that class.
C# provides following two techniques to manipulate private data members:
1) Enforcing Encapsulation Using Traditional Accessors & Mutators
Consider, if we wish to provide safe access to the Employee's internal "fullName" data
member, we would write
public class Employee
{
private string fullName;
public string GetFullName()
//Accessor
{
return fullName;
}
public void SetFullName(string s)
//mutator
{
//remove any illegal characters(# ! ?)
//check maximum length before making assignment
fullName=s;
}
}
In the above example, GetFullName() and SetFullName() encapsulate a private string named
Any attempt to make assignments to a field marked "readonly" results in a compiler error.
Greatness arrives for those who are never satisfied with what is, no matter how nice it looks.
66
Here, PTSSalesPerson is a class representing a part-time SalesPerson. To prevent other classes from
Because PTSalesPerson is sealed, it cannot serve as a base class to any other type. Thus, if we
public Car()
{ MaxSpeed=100}
public Car(string n, int m, int c)
{
name=n;
MaxSpeed=m;
CurrSpeed=c;
}
public void SpeedUp(int a)
{
if(carIsDead)
Console.WriteLine(Out of order);
else
{
CurrSpeed+=a;
}
}
Now, we have two classes viz. Radio and Car. Here, we can say, Car has a Radio. Now, the Car is
To expose the functionality of the inner class to the outside world requires delegation.
Delegation is the act of adding members to the containing class that make use of the functionality of
contained class.
class Car
{.
public void Tune(bool s)
{
rd.TurnOn(s);
}
}
Thus by making one class to be a member of other class, we can establish has-a relationship. But it is
always the job of outer class to define a member function which activates the inner class objects.
Now, the classes Manager and SalesMan both contains the method Bonus(float). Thus in the Main()
function, we can call Bonus() through the objects of Manager and SalesMan
Manager m=new Manager();
m.Bonus(500);
SalesMan s=new SalesMan()
s.Bonus(300);
Obviously, the Bonus() method works same for both the objects. With the help of virtual and
override keywords, we can make same function to behave differently in base-class and all the derived
classes. For example,
class Employee
{
-----------------public virtual void Bonus(float b)
{
basicSal+=b;
}
}
class SalesMan:Employee
{
-----------------public override void Bonus(float b)
{
int salesBonus=0;
if(numOfSales<=100)
salesBonus=10;
elseif (numOfSales<=200)
salesBonus=20;
base.Bonus(b*salesBonus);
}
//use
of
base
class
method
class Test
{
public static void Main()
{
Employee e=new Employee();
e.Bonus(100);
//base class Bonus() is called
SalesMan s=new SalesMan()
s.Bonus(300);
//derived class Bonus() is called
}
}
We can see that when the Bonus() method is invoked through base class object, the corresponding
method will be called. Whereas, when Bonus() is invoked with the object s of derived class, the
overridden method Bonus() will be called.
Life has a very fair accounting system & as one sows, one will reap.
69
ABSTRACT METHOD
Abstraction refers to the act of representing essential features without including the background
details or explanation.
Abstract base class may define any number of abstract members.
"Abstract" keyword is used to define a method that does not provide a default implementation.
Abstract method is equivalent to pure virtual functions of C++.
To understand the need for abstract methods, consider the following figure 4-11:
By making a base class method as abstract, we are making use of run-time polymorphism or late
binding. That is, the binding between the object and the method to be invoked is decided only at
runtime.
A mind once stretched by a new idea can never return to its original dimensions.
70
Now, when we create an object of Oval class and invoke Draw() method, the most recently used
Thus, the keyword new breaks the relationship between the abstract Draw() method defined by the
In all these situations, the implicit casting from derived class to base class is done by the C# CLR.
On the other hand, when we need to convert base class reference to be stored in derived class
Here, the explicit cast from base class to derived class is done.
In all these situations, the implicit casting from derived class to base class is done by the C# CLR.
On the other hand, when we need to convert base class reference to be stored in derived class
Here, the explicit cast from base class to derived class is done.
The usage of other two methodologies is depicted with the help of examples:
Object ob=new Manager();
if(ob is Manager)
//do something
Employee e;
SalesMan s= e as SalesMan;
//do something with s
Numerical Casts
In addition to casting between objects, the numerical conversions also follow similar rules. When we
are trying to cast larger (in size of type) type to smaller type, we need to make explicit casting:
int x=25000;
byte b=(byte)x; //loss of information
While converting from larger type to smaller type, there is a chance of data-loss.
When we need to cast smaller type to larger type, the implicit casting is done automatically:
byte b=23;
int x=b;
//implicit casting
Your schedule is the best barometer for what you truly value & believe to be important.
72
..
class C2
{
}
EXERCISES
1. Explain method overloading with example. (4)
2. Explain self reference in C# with example. (6)
3. Explain "Default Public Interface" of a type. (4)
4. Explain public and internal types with example. (6)
5. Explain is-a and has-a relationship with respect to inheritance. (6)
6. Compare classical vs. adhoc polymorphism. (6)
7. What is encapsulation? What are two ways of enforcing encapsulation? Give examples
for both the methods. (8)
8. Explain read only and write only properties with example. (6)
9. Explain static properties with example. (4)
10. Explain pseudo encapsulation with example. (4)
11. How do you prevent inheritance using sealed classes? Explain with an example. (6)
12.
13.
14.
15.
16.
Write a
Explain
Explain
What do
Write a
Great achievement often happens when our backs are up against the wall.
Pressure can actually enhance your performance.
74
ob.Fun(d);
Output:
Enter a number: 12
speed is =12
Enter a number: 567
Unhandled Exception: System.Exception: crossed limit!!!
at Test.Fun(Int32 d)
at Test.Main()
In the above example, if the entered-value d is greater than 100, then we throw an exception.
Firstly, we have created a new instance of the System.Exception class,
then we have passed a message crossed limit to a Message property of Exception class.
It is upto the programmer to decide exactly
what constitute an exception &
when the exception should be thrown.
Using throw keyword, program throws an exception when a problem shows up.
ob.Fun(d);
Output-1:
Enter a number: 12
Speed is =12
Output-2:
Enter a number: 123
Message: crossed limit!!!
Method: Void Fun(Int32)
Speed is=123
A try block contains a code that will check for any exception that may be encountered during its
scope.
If an exception is detected, the program control is sent to the appropriate catch-block. Otherwise,
the catch-block is skipped.
Once an exception is handled, the application will continue its execution from very next point after
catch-block.
result=SafeDivision(num1,num2);
}
catch( DivideByZeroException e)
{
Console.WriteLine("Error message = {0}", e.Message);
}
finally
{
Console.WriteLine("Result: {0}", result);
}
Output:
Error message = you cannot divide a number by 0
Result: 0
No life is perfect. We all must face challenges, both large & small.
77
//the error has been handled, continue with the flow of this application
Console.WriteLine("Speed is ={0}", d);
Output:
ob.Fun(d);
Enter a number=127
Error caught!
Class defining member= Test
Member type= Method
Member name= Void Fun(Int32)
Message= crossed limit!!!
Stack= at Test.Fun(Int32)
Help link= g:\Help.doc
Speed is =127
The relationship between exception-centric base classes are shown below (Figure 5.1)
result=SafeDivision(num1,num2);
}
catch(DivideByZeroException e)
{
Console.WriteLine("Error message = {0}", e.Message);
}
catch(OutOfMemoryException e)
{
Console.WriteLine("Error message = {0}", e.Message);
}
catch(Exception e)
{
Console.WriteLine("Error message = {0}", e.Message);
}
finally
{
Console.WriteLine("Result: {0}", result);
}
Output:
Error message = you cannot divide a number by 0
Result: 0
Here, the class Exception is a base class for all custom and system exceptions. Hence, it can handle
any type of exceptions.
If Exception is the first catch-block, the control will jump to that block itself and the other two
exceptions are unreachable.
Thus, we have to make sure the catch-blocks are structured such that
the very first catch is the most specific exception(or most derived type in inheritance hierarchy)
whereas the final catch is the most general (or top most base class in inheritance hierarchy).
If we keep doing things the same way, we're only going to see the same results.
81
But, using this type of catch blocks indicates that the programmer is un-aware of the type of
exception that is going to occur, which is not acceptable. Hence it is always advised to use specific type
of exceptions.
RETHROWING EXCEPTIONS
To re-throw exception, simply make use of the "throw" keyword within a catch-block.
try
{...}
catch(CarIsDeadException e)
{
throw e
}
//do something
}
catch(ApplicationException e)
{
--------------}
catch(SystemException e)
{
--------------}
Though C# has the ability to discover at runtime the underlying source of an exception, we are
gaining nothing by doing so.
Because some BCL methods that should ideally throw a type derived from System.SystemException.
are actually derived from System.ApplicationException or even more generic System.Exception.
EXERCISES
1. Differentiate between bugs, errors and exceptions. Explain the
exception handling. (6)
2. Define the following keywords with program: (6)
i)try
ii)throw
iii)catch
iv)finally
3. List out & explain core members of System.Exception class. (4)
4. With a program, explain & illustrate the use of System.Exception
throwing generic exceptions. (6)
5. With a program, explain & illustrate the use of System.Exception
catching exceptions. (6)
6. Briefly explain the usage of finally block. (4)
7. With a program, explain following properties: TargetSite, StackTrace,
8. Compare System level exception vs. Application level exception. (4)
9. With a program, explain how to build custom exception. (6)
10. Write C# application to illustrate handling multiple exceptions. (4)
11. Why is proper ordering of catch blocks necessary in C#? (4)
role
of
.NET
base class in
base class in
HelpLink. (6)
Here, c is created within the scope of Main(). Thus, once the application shuts down, this reference is
no longer valid and therefore it is a candidate for garbage collection.
But, we cannot surely say that the object c is destroyed immediately after Main() function. All we
can say is when CLR performs the next garbage collection; c is ready to be destroyed.
THE CIL OF "new"
When C# compiler encounters the 'new' keyword, it will emit a CIL newobj" instruction to the codemodule.
The garbage-collector(GC) is a tidy house-keeper.
GC compacts empty blocks of memory for purpose of optimization.
The heap maintains a new-object-pointer(NOP).
NOP points to next available slot on the heap where the next object will be placed.
The newobj instruction informs CLR to perform following sequence of events:
1) CLR calculates total memory required for the new object to be allocated (Figure 5.2).
If this object contains other internal objects, their memory is also taken into account.
Also, the memory required for each base class is also taken into account.
2) Then, CLR examines heap to ensure that there is sufficient memory to store the new object.
If yes, the object's constructor is called and a reference to the object in the memory is returned
(which just happens to be identical to the last position of NOP).
3) Finally, CLR advances NOP to point to the next available slot on the heap.
After garbage-collection, the NOP is readjusted to point to the next available slot as shown in the
following diagram (Figure 5.4):
Every man takes the limits of his own field of vision for the limits of the world.
84
The C# destructor style syntax can be understood as a shorthand notation for the following code:
protected override void Test()
{
try
{
Console.WriteLine("->finalizing test ")
finally
{base.Finalized(); }
}
}
}
Output:
Within Main()
Exiting Main()
Finalizing Test!!!
When things go good, we feel happy. When things go bad, we feel sad.
This kind of approach to living is a weak way to live
85
Now, the application can implement this interface and define Dispose() method.
Rule: Always call Dispose() for any object we manually allocate to heap. The assumption we should
make is that if class designer chose to support Dispose() method, type has some cleanup to perform.
public Car:IDisposable
{
public void Dispose()
{
//clean up your internal unmanaged resources
}
}
public class App
{
public static int Main(string[] args)
{
Car c1=new Car("car one",40,10);
c1.Dispose();
return 0;
}
}
Dispose() method can be called manually before the object goes out of scope.
This method will take care of cleaning up the unmanaged resources.
This method will
avoid object being placed at finalization-queue & avoid waiting for garbage collector to clean-up
We all have to do our interior work. It's our highest responsibility.
86
C# provides another way of doing this with the help of using keyword:
public void Test()
{
using(Car c=new Car())
{
//Do something
//Dispose() method is called automatically when this block exits
}
}
One good thing here is, the Dispose() method is called automatically when the program control
comes out of using block.
But there is a disadvantage: If at all the object specified at using does not implement IDisposable,
then we will get compile-time error.
GARBAGE COLLECTION OPTIMIZATION
To locate unreachable objects, CLR does not inspect every object placed on heap to find orphanedroots. Because, doing so will consume more time for larger applications.
Each object on the heap is assigned to a given "generation".
The main idea behind generation:
The longer an object has existed on the heap; the more likely it is to stay there.
For example, application-level objects.
Conversely, if an object is recently placed on heap; it may be dereferenced by application quickly.
For example, objects within a scope of a method.
Each object belongs to one of following generations:
i) Generation-0(G0): Identifies a newly allocated object that has never been marked for
garbage collection.
ii) Generation-1(G1): Identifies an object that has survived one garbage collection sweep.
iii) Generation-2(G2): Identifies an object that has survived more than one garbage collection
sweep.
Now, when garbage collection occurs, the GC marks and sweeps all generation-0 objects first.
If this results in the required amount of memory, the remaining objects are promoted to the next
available generation (G0->G1 & G1->G2).
If all generation-0 objects have been removed from the heap, but more memory is still necessary,
generation-1 objects are marked and swept, followed(if necessary) by generation-2 objects.
CORE MEMBERS OF SYSTEM.GC TYPE
Member
Collect ()
GetTotalMemory()
GetGeneration()
MaxGeneration()
ReRegisteredForFinalize()
SuppersFinalize()
WaitForPendingFinalizers()
Meaning
This forces GC to call the Finalize() method for every object on managed-heap.
This returns the estimated amount of memory currently being used by all objects in
the heap.
This returns the generation to which an object currently belongs.
This returns the maximum generations supported on the target system.
This sets a flag indicating that the suppressed-object should be reregistered as
finalize.
This sets a flag indicating that a given object's Finalize() method should not be called.
This suspends the current thread until all finalizable objects have been finalized.
This method is typically called directly after invoking GC.Collect().
Man's main task in life is to give birth to himself, to become what he potentially is.
87
class Test
{
public static void Main()
{
Car c1=new Car("One");
Car c2=new Car("Two");
Car c3=new Car("Three");
Car c4=new Car("Four");
Output:
Within
Within
Within
Within
c1.Dispose();
c3.Dispose();
Dispose() of One
Dispose() of Three
destructor of Four
destructor of Two
Both Dispose() and Finalize() (or destructor) methods are used to release the unmanaged resources.
As we can see in the above example, when Dispose() method is invoked through an object, we can
prevent the CLR from calling the corresponding destructor with the help of SuppressFinalize() method
of GC class.
By manually calling Dispose() method, we are releasing the resources and hence there is no need to
call finalizer.
Calling the Dispose() function manually is termed as explicit object de-allocation and making use of
finalizer is known as implicit object de-allocation.
FORCING A GARBAGE COLLECTION
We know that, CLR will automatically trigger a garbage collection when a managed heap is full.
We, the programmers, will not be knowing, when this process will happen.
However, if we wish, we can force the garbage collection to occur using the following statements:
GC.Collect();
GC.WaitForPendingFinalizers();
The method WaitForPendingFinalizers() will allow all finalizable objects to perform any necessary
cleanup before getting destroyed. Though, we can force garbage collection to occur, it is not a good
programming practice.
The starting point of enlightenment, a goal that every person should strive for, is inner leadership.
88
}
class Test
{
C1 is Gen 0
C2 is Gen 0
C3 is Gen 0
C4 is Gen 0
Within Dispose() of One
Within Dispose() of Three
C1 is Gen 1
C2 is Gen 1
C3 is Gen 1
C4 is Gen 1
Within Destructor of Four
Within Destructor of Two
EXERCISES
1. Explain object lifetime in .NET. (6)
2. Explain the CIL of "new". (6)
3. Describe the role of .NET garbage collection. (6)
4. Explain finalizing a type in.NET. (4)
5. With program,explain how to invoke System.Object.Finalize() indirectly (4)
6. Explain finalization process in .NET. (6)
7. Explain adhoc destruction method. (4)
8. With a program, explain the use of IDisposable interface. (4)
9. Explain use of using keyword with respect to garbage collection. (4)
10. Explain how garbage collection is optimized in .NET. (6)
11. List out & explain core members of System.GC class. (4)
12. With a program, explain how to build finalization & disposable types. (6)
13. With a program, explain how to interact with generations. (6)
To have new things in your life such as new levels of joy and new experiences of fulfillment, you must begin to do
new things.
89
Interface-types are somewhat useless on their own (as they are nothing more than a namedcollection of abstract-members). Given this, we cannot allocate interface-types:
// Ack! Illegal to "new" interface types.
static void Main(string[] args)
{
IPointy p = new IPointy();
// Compiler error!
}
IMPLEMENTING AN INTERFACE
A class/structure can extend its functionality by supporting a given interface using a commadelimited list in the type-definition.
// This class derives from System.Object and implements single interface.
public class SomeClass : ISomeInterface
{ ...
}
// This struct derives from System.ValueType and implements 2 interfaces.
public struct SomeStruct : ISomeInterface, IPointy
{ ...
}
// IPointy Implementation.
// IPointy Implementation.
Here, each class returns its number of points to the caller when asked to do so.
It takes great inner power to take a serious look at the way we're living & make the midcourse corrections that will
set up back on track.
90
Following 3 methods can be used to check which interfaces are supported by a given type:
Method 1: Explicit Casting
An explicit-cast can be used to obtain an interface-reference.
When we attempt to access an interface not supported by a given class using a direct-cast, the
runtime throws an InvalidCastException.
public static void Main(string[] args)
{
Hexagon hex=new Hexagon("bill");
IPointy ipt;
try
{
ipt=(IPointy)hex;
// explicit casting
Console.WriteLine(ipt.GetNumberOfPoints());
}
catch (InvalidCastException e)
{
Console.WriteLine(e.Message);
}
}
We may discover at runtime which items in the array support this behavior. For example,
public static void Main(string[] args)
{ Shape[ ] s = { new Hexagon(), new Circle(), new Triangle("Ram"), new Circle("Sham")} ;
for(int i = 0; i < s.Length; i++)
{
//Recall the Shape base class defines an abstract Draw() member, so all shapes know how to draw themselves.
s[i].Draw();
if(s[i] is IPointy)
Console.WriteLine("Points: {0} ", ((IPointy)s[i]).GetNumberOfPoints());
else
Console.WriteLine("OOPS! Not Pointy");
}
}
We all have our blind spots -- we need to acknowledge them and bring them into the light of awareness,
where they'll be healed.
92
Next, assume that two of our three shapes (Circle and Hexagon) have been configured to support
this new behavior:
// Circle supports IDraw3D
public class Circle : Shape, IDraw3D
{
public void Draw3D()
{
Console.WriteLine("Drawing Circle in 3D!");
}
}
// Hexagon supports IPointy and IDraw3D
public class Hexagon : Shape, IPointy, IDraw3D
{
public void Draw3D()
{
Console.WriteLine("Drawing Hexagon in 3D!");
}
}
If we now define a method taking an IDraw3D interface as a parameter, we are able to effectively
send in any object implementing IDraw3D (if we attempt to pass in a type not supporting the
necessary interface, we receive a compile-time error).
Consider the following:
// Make some shapes. If they can be rendered in 3D, do it!
public class Program
{
// I'll draw anyone supporting IDraw3D.
public static void DrawIn3D(IDraw3D itf3d)
{
Console.WriteLine("Drawing IDraw3D compatible type");
itf3d.Draw3D();
}
The greater the gap between who you are on the inside and the way you occur on the outside,
the greater the unhappiness you'll feel in your life
93
Interface as Polymorphic Agent: This can be very helpful when we want to implement a number of
interfaces that happen to contain identical methods. For e.g.:
public interface IDraw
{
void Draw();
public interfaceIDraw3D
{
void Draw();
}
}
You wouldn't be able to see the great quality of another person unless you knew that quality in yourself.
94
Output:
Basic drawing logic
Render to metafile
Draw to printer
Living your best life is really mostly about recapturing what you gave up.
95
interface IUnderwaterCar
{
void Dive();
If we were to build a class that implements IJamesBondCar, we would now be responsible for
implementing TurboBoost(), Dive(), and Drive():
public class JamesBondCar : IJamesBondCar
{
public void Drive()
{
Console.WriteLine("Speeding up...");
}
public void Dive()
{
Console.WriteLine("Submerging...");
}
public void TurboBoost()
{
Console.WriteLine("Blast off!");
}
}
Output:
Speeding up...
Blast off!
Submerging
All the things you dont like about your life are actually your best friends & greatest teachers because they help you get
to your destination--your ideal life.
96
IConvertible.GetTypeCode()
GetTypeCode() method can be used to programmatically discover a value that represents type-code
of the data-type.
The System.Convert Type
System namespace defines a data-type named Convert, which echoes the functionality of
IConvertible interface.
System.Convert does not directly implement IConvertible, however the same set of members are
defined on its default public interface.
Just keep choosing the highest, most loving possible response in every situation. It'll get easier in time, and the results
will be astounding
97
GetEnumerator()
method
returns
a
reference
to
yet
another
interface
named
System.Collections.IEnumerator.
IEnumerable interface allows the caller to traverse the internal objects contained by the
IEnumerable-compatible container.
Here is the formal definition:
//This interface informs the caller that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
// This interface allows the caller to obtain a container's subitems.
public interface IEnumerator
{
bool MoveNext ();
// Advance the internal position of the cursor.
object Current { get;}
// Get the current item (read-only property).
void Reset ();
// Reset the cursor before the first member.
}
using System.Collections;
public class Garage : IEnumerable
{
// System.Array already implements IEnumerator!
private Car[] carArray;
public Garage()
{
carArray = new Car[4];
carArray[0] = new Car("FeeFee", 200, 0);
carArray[1] = new Car("Clunker", 90, 0);
carArray[2] = new Car("Zippy", 30, 0);
carArray[3] = new Car("Fred", 30, 0);
}
Once we have updated our Garage type, we can now safely use the type within the foreach loop.
Furthermore, given that the GetEnumerator() method has been defined publicly, the object user
could also interact with the IEnumerator type:
static void Main(string[] args)
{
// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName,myCar.CurrSpeed);
Output:
X = 100; Y = 100
X = 0; Y = 100
Every experience that intersects with your life comes to you to teach you the lesson you most need to learn to rise to
the next platform of your life.
99
interface IComparable
// the formal definition
{
int CompareTo(object o);
}
public class Car
{
private int carID;
public int ID
{
get { return carID; }
set { carID = value; }
}
public Car(string name, int currSp, int id)
{
currSpeed = currSp;
petName = name;
carID = id;
}
}
public class Car: IComparable
{
int IComparable.CompareTo(object o)
{
Car temp=(Car)o;
if(this.CarID>temp.CarID)
return 1;
if(this.CarID<temp.CarID)
return -1;
else
return 0;
}
}
public class CarApp
{
public static int Main(string[] args)
{
Car[] myAutos=new Car[3];
myAutos[0]=new Car(112,"mary");
myAutos[1]=new Car(11,"jimmy");
myAutos[2]=new Car(21,"rusty");
Consoe.WriteLine("here is the unordered set of cars");
foreach(Car c in myAutos)
Console.WriteLine("{0} {1}",c.ID,c.PetName);
Array.Sort(myAutos);
Console.WriteLine("here is the ordered set of cars");
foreach(Car c in myAutos)
Console.WriteLine("{0} {1}",c.ID, c.PetName);
return 0;
}
}
Output: here is the unordered set of cars
112 mary
11 jimmy
21 rusty
here is the ordered set of cars
11 jimmy
21 rusty
112 mary
Queue
SortedList
Stack
Key Implemented
Interfaces
IList, ICollection,
IEnumerable, and
ICloneable
IDictionary,
ICollection,
IEnumerable, and
ICloneable
ICollection,
ICloneable, and
IEnumerable
IDictionary,
ICollection,
IEnumerable, and
ICloneable
ICollection,
ICloneable, and
IEnumerable
The true joy in life appears once it's shared with someone you love.
102
Here we are making use of the AddRange() method to populate our ArrayList with a set of Car types
(this is basically a shorthand notation for calling Add() n number of times).
Once we print out the number of items in the collection (as well as enumerate over each item to
obtain the pet name), we invoke Insert().
The Insert() allows to plug a new item into the ArrayList at a specified index.
Finally, notice the call to the ToArray() method, which returns a generic array of System.Object types
based on the contents of the original ArrayList.
The journey of life is all about--spotting our weaker areas & healing them so that we eventually find our best selves.
103
Output
catch(Exception e)
{
Console.WriteLine("error {0}",e.Message);
}
first in Q is firstcar
cleaning firstcar
cleaning secondcar
cleaning thirdcar
error! Queue empty
The soul would rather fail at its own life than succeed at someone else's.
104
Output:
catch(Exception e)
{ Console.WriteLine("Error!! {0}", e.Message); }
The only devils in the world are those running in our own hearts. That is where the battle should be fought.
105
EXERCISES
1) Bring out the differences between interface and abstract base classes. (6)
2) How do you implement an interface? Explain with an example. (6)
3) Explain different techniques for invoking interface members at object level. (6)
4) Explain with example, explicit interface implementation. (6)
5) Explain with example, interface hierarchy. (6)
6) Explain with example, multiple base interfaces. (4)
7) How do you pass interface as parameter to a method? Explain with an example. (4)
8) Explain the concept of interface-based polymorphism. (4)
9) Explain any two methods of IConvertible interface. (6)
10) Explain usage of IEnumerable & IEnumerator interfaces with suitable examples. (6)
11) What do you mean by cloneable object? Write an example to depict the implementation
of ICloneable Interface. (6)
12) Illustrate with an example, implementation of IComparable interface. (6)
13) List out & explain interfaces provided by System.Collection namespace. Draw diagram
to show hierarchical relationship that exists b/w these interfaces. (6)
14) What are the major classes in System.Collections namespace? Explain. (4)
15) Write a code segment to illustrate the working of ArrayList class. (4)
16) What the members of System.Collection.Queue? Explain. (4)
17) Write a code snippet to show the usage of Stack class. (4)
NOTE: Since this is a programming subject, you can expect atleast 50% of the questions on C# programs in the
examination. So, here I am providing a link from which you can download C# programs from Balagurusamy
text book as per the syllabus.
http://vtunotesbysri.weebly.com/uploads/4/2/5/8/42583203/c_sharp_balguruswamy_programs.rar