Handout: C#
Version: C#/Handout/0308/1.0 Date: 10-04-08
Cognizant 500 Glen Pointe Center West Teaneck, NJ 07666 Ph: 201-801-0233 www.cognizant.com
TABLE OF CONTENTS
Introduction ... 8
About this Module ... 8
Target Audience ... 8
Module Objectives ... 8
Pre-requisite ... 8
Session 02: Overview of .NET Framework ... 9
Learning Objectives ... 9
Overview of .Net Framework ... 9
Common Language Runtime ... 9
CommonTypeSystem ... 10
Common Language Specification ... 11
Assembly ... 12
Application Domains ... 13
Runtime Hosts ... 14
Garbage Collection ... 15
Summary ... 16
Test Your Understanding ... 16
Session 03: Introduction to C# ... 17
Learning Objectives ... 17
C# Variables, Identifiers and Keywords ... 17
C# Statements ... 18
Identifiers ... 23
Keywords ... 23
Console Applications ... 24
Summary ... 25
Test Your Understanding ... 25
Session 05: Data Types and Control Flow ... 26
Learning Objectives ... 26
Data Types ... 26
Boxing and UnBoxing ... 33
Operators ... 35
Control Flow ... 37
Test your Understanding ... 44
Session 08: Arrays, Methods and Parameters ... 45
Learning Objectives ... 45 Arrays ... 45 Methods ... 50 Parameters ... 51 Method Overloading ... 53 Summary ... 54
Test your Understanding ... 54
Session 11: Creating Value with Enumerations and Structs ... 55
Learning Objectives ... 55
Enumerations ... 55
Structs ... 57
Summary ... 58
Test your Understanding ... 58
Session 12: Classes and Objects ... 59
Learning Objectives ... 59
Fundamentals of object-oriented programming ... 59
Characteristics of an object-oriented language ... 60
Inheritance, Overriding and Overloading ... 61
Polymorphism ... 64
Summary ... 66
Test your Understanding ... 66
Session 13: Classes and Objects ... 67
Learning Objectives ... 67
Classes and Objects ... 67
Properties ... 68
Indexers ... 69
Access Modifiers... 72
Summary ... 78
Test your Understanding ... 78
Session 14: Classes and Objects ... 79
Learning Objectives ... 79
Partial Classes ... 80
Nested Classes ... 82
Summary ... 83
Test your Understanding ... 83
Session 17: Inheritance and Interface ... 84
Learning Objectives ... 84
Inheritance ... 84
Abstract Class ... 85
Interface ... 86
Summary ... 88
Test Your Understanding ... 88
Session 21: Nunit ... 89
Learning Objectives ... 89
Nunit: ... 89
Summary ...102
Test your Understanding ...102
Session 23: Generics and Collections ...103
Learning Objectives ...103
Generics ...103
Classes in Generics ...105
Summary ...111
Test Your Understanding ...112
Session 24: Generics and Collections ...113
Learning Objectives ...113
Collections ...113
Defining Collections ...113
Commonly Used Collection Types ...113
Creating and manipulating collection ...114
When to use Generics collections ...114
Classes in collections ...114
Summary ...122
Test Your Understanding ...122
Session 27: Exception Handling ...123
Exception handling in C# ...123
Throw Statement ...125
Finally Statement ...125
User Defined Exceptions ...126
Exception Type ...126
Summary ...128
Test your Understanding ...129
Session 30: File Handling ...130
Learning Objectives ...130 Stream Class ...130 Binary Reader ...132 Binary Writer ...133 Text Reader ...134 Text Writer ...136
File I/O Operations ...139
Stream Reader Class ...139
Stream Writer Class ...140
Summary ...142
Test Your Understanding ...142
Learning Objectives ...143
XML ...143
XML Document Object Model ...146
Reading XML with the XmlReader ...149
Writing XML with the XmlWriter ...150
Summary ...152
Test your Understanding ...152
Session 34: Delegates and Events ...153
Learning Objectives ...153
Events and Delegates: ...153
Summary ...160
Test your Understanding ...160
Session 37: Multithreading ...161
Learning Objectives ...161
Multithreading ...161
Thread States: ...161
The Thread Pool class ...162
Multithreading in C# ...162
Advantages and Disadvantages of Multithreading ...164
Summary ...164
Test Your Understanding ...165
Session 40: Reflection and Serialization ...166
Learning Objectives ...166
Reflection ...166
Summary ...169
Test Your Understanding ...169
Session 42: Reflection and Serialization ...170
Learning Objectives ...170
Overview ...170
What is Serialization and De-serialization? ...170
Working with formatters: ...173
Advantages and disadvantages of serialization ...174
Summary ...174
Test Your Understanding ...174
Session 45: .NET Interoperability ...175
Learning Objectives ...175
Overview of .NET and COM interoperability ...175
Interoperability through Runtime wrappers ...175
Programming Model comparison of .NET-COM interoperability ...176
.NET Marshalling ...177
Interop marshaler ...177
COM Marshaler ...178
Summary ...178
Test your Understanding ...179
Session 47: Remoting ...180
Learning Objectives ...180
.NET Remoting basics ...180
.NET Remoting concepts ...180
.NET Remoting Architecture ...183
Summary ...184
Session 48: Remoting ...186
Learning Objectives ...186
Remoting Application: ...186
Summary ...190
Test your Understanding ...190
Session 50: Garbage Collection and Memory Management ...191
Learning Objectives ...191 Memory Management ...191 Allocating Memory ...191 Releasing Memory ...191 Garbage Collection: ...193 Summary ...200
Test your Understanding ...200
Glossary ...201
References ...208
Websites ...208
Books ...208
Introduction
About this Module
This module provides developer with the knowledge and skills that are needed to develop and implement applications using C#.NET.
Target Audience
This module is designed for entry level developers using C# and .NET technologies.
Module Objectives
After completing this module, you will be able to: Describe features of C#
Apply .NET Framework technologies like BCL, Remoting, Reflection, and Interop in C# Explain and write C# programs using variables, arrays, operators, and namespaces Write C# programs implementing exceptions handling
Describe Object oriented programming in C#
Explain threading concept and write multi-threaded programs Explain input output operations in C#
Interoperate with legacy COM
Define the concepts of Delegates, Events, Reflection, and Remoting
Pre-requisite
Working knowledge in any object oriented programming language and a basic understanding of .NET technologies.
Session 02: Overview of .NET Framework
Learning Objectives
After completing this session, you will be able to: Describe the .NET Framework
Explain Common Language Runtime (CLR), Explain Common Type System (CTS), and Common Language system (CLS)
Explain Assembly and Application Domain Describe Runtime Host and Garbage Collection
Overview of .Net Framework
The .NET Framework is an integral Windows component that supports building and running the next generation of applications and XML Web services.
The .NET Framework is designed to fulfill the following objectives:
To provide a consistent object-oriented programming environment whether object code is stored and executed locally, executed locally but Internet-distributed, or executed remotely.
To provide a code-execution environment that minimizes software deployment and versioning conflicts.
To provide a code-execution environment that promotes safe execution of code, including code created by an unknown or semi-trusted third party.
To provide a code-execution environment that eliminates the performance problems of scripted or interpreted environments.
To make the developer experience consistent across widely varying types of applications, such as Windows-based applications and Web-based applications. To build all communication on industry standards to ensure that code based on the
.NET Framework can integrate with any other code.
The .NET Framework has two main components: Common language runtime
.NET Framework class library.
Common Language Runtime
The common language runtime makes it easy to design components and applications whose objects interact across languages. Objects written in different languages can communicate with each other and their behaviors can be tightly integrated.
For example, you can define a class and then use a different language to derive a class from your original class or call a method on the original class and also pass an instance of a class to a method of a class written in a different language. This cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime, and they follow the runtime's rules for defining new types, as well as for creating, using, persisting, and binding to types.
Benefits of the CLR are as follows: Performance improvements.
The ability to easily use components developed in other languages. Extensible types provided by a class library.
A CLR feature includes the following:
Cross-language integration, especially cross-language inheritance.
Garbage collection, which manages object lifetime so that reference counting is unnecessary.
Self-describing objects, which make using Interface Definition Language (IDL) unnecessary.
The ability to compile once and run on any CPU and operating system that supports the runtime.
CommonTypeSystem
The common type system defines how types are declared, used, and managed in the runtime, and is also an important part of the runtime's support for cross-language integration.
The common type system performs the following functions:
Establishes a framework that helps enable cross-language integration, type safety, and high performance code execution.
Provides an object-oriented model that supports the complete implementation of many programming languages.
Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.
Classification of Types:
The common type system supports two general categories of types, each of which is further divided into subcategories:
Value types: Value types directly contain their data, and instances of value types are either allocated on the stack or allocated inline in a structure. Value types can be built-in (implemented by the runtime), user-defbuilt-ined or enumerations
Reference types: Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. The type of a reference type can be determined from values of self-describing types. Self-describing types are further split into arrays and class types. The class types are user-defined classes, boxed value types, and delegates.
The following example shows the difference between reference types and value types: using System;
class Class1 {
public int Value = 0; }
class Test {
static void Main() { int val1 = 0; int val2 = val1; val2 = 123;
Class1 ref1 = new Class1(); Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); }
}
Type classification:
Common Language Specification
It is a set of basic language features needed by many applications, has been defined. The CLS rules define a subset of the Common Type System. All the rules that apply to the common type system apply to the CLS, except where stricter rules are defined in the CLS.
Assembly
Assemblies are a fundamental part of programming with the .NET Framework. It contains code that the common language runtime executes. Microsoft intermediate language (MSIL) code in a portable executable (PE) file will not be executed if it does not have an associated assembly manifest.
Assemblies can be static or dynamic. Static assemblies can include .NET Framework types (interfaces and classes), as well as resources for the assembly (bitmaps, JPEG files, resource files, and so on). Static assemblies are stored on disk in portable executable (PE) files. We can also use the .NET Framework to create dynamic assemblies, which are run directly from memory and are not saved to disk before execution. We can save dynamic assemblies to disk after they have executed.
Assembly Benefits:
Assemblies are designed to simplify application deployment
It solves versioning problems that can occur with component-based applications It provides the infrastructure to allow multiple versions of a component to be run
simultaneously.
Assembly Manifest: Every assembly, whether static or dynamic, contains a collection of data that describes how the elements in the assembly relate to each other. The assembly manifest contains this assembly metadata.
The following illustration shows the different ways the manifest can be stored:
For an assembly with one associated file, the manifest is incorporated into the PE file to form a single-file assembly. You can create a multifile assembly with a standalone manifest file or with the manifest incorporated into one of the PE files in the assembly.
Each manifest of assembly performs the following functions: Enumerates the files that make up the assembly.
Governs how references to the assembly's types and resources map to the files that contain their declarations and implementations.
Provides a level of indirection between consumers of the assembly and the assembly's implementation details.
Renders the assembly self-describing.
Assembly Manifest Contents:
The following table shows the information contained in the assembly manifest. The first four items—the assembly name, version number, culture, and strong name information—make up the assembly's identity.
Information Description
Assembly name A text string specifying the assembly's name.
Version number A major and minor version number, and a revision and build number. The common language runtime uses these numbers to enforce version policy. Culture Information on the culture or language the assembly supports. This
information should be used only to designate an assembly as a satellite assembly containing culture- or language-specific information. (An assembly with culture information is automatically assumed to be a satellite assembly.) Strong name
information
The public key from the publisher if the assembly has been given a strong name.
List of all files in the assembly
A hash of each file contained in the assembly and a file name. Note that all files that make up the assembly must be in the same directory as the file containing the assembly manifest.
Type reference information
Information used by the runtime to map a type reference to the file that contains its declaration and implementation. This is used for types that are exported from the assembly.
Information on referenced assemblies
A list of other assemblies that are statically referenced by the assembly. Each reference includes the dependent assembly's name, assembly metadata (version, culture, operating system, and so on), and public key, if the assembly is strong named.
Application Domains
Application domains provide a flexible and secure method of isolating running applications. Application domains are usually created and manipulated by run-time hosts.
Application domains aid security, separating applications from each other and each other's data. A single process can run several application domains, with the same level of isolation that would exist in separate processes. Running multiple applications within a single process increases server scalability.
In the following code example, you create a new application domain and then load and execute a previously built assembly, HelloWorld.exe that is stored on drive C.
static void Main() {
// Create an Application Domain: System.AppDomain newDomain=
System.AppDomain.CreateDomain("NewApplicationDomain");
// Load and execute an assembly:
newDomain.ExecuteAssembly(@"c:\HelloWorld.exe");
// Unload the application domain: System.AppDomain.Unload(newDomain); }
Application domains have the following properties:
An assembly must be loaded into an application domain before it can be executed. Faults in one application domain cannot affect other code running in another
application domain.
Individual applications can be stopped and code unloaded without stopping the entire process. Cannot unload individual assemblies or types, only entire application domains.
Advantages of Application Domain:
Faults in one application cannot affect other applications. Because type-safe code cannot cause memory faults, using application domains ensures that code running in one domain cannot affect other applications in the process.
Individual applications can be stopped without stopping the entire process. Using application domains enables you to unload the code running in a single application. Code running in one application cannot directly access code or resources from
another application.
The behaviour of code is scoped by the application in which it runs. In other words, the application domain provides configuration settings such as application version policies, the location of any remote assemblies it accesses, and information about where to locate assemblies that are loaded into the domain.
Permissions granted to code can be controlled by the application domain in which the code is running.
Runtime Hosts
The common language runtime has been designed to support a variety of different types of applications from Web server applications to applications with a traditional rich Windows user interface.
Each type of application requires a runtime host to start it.
The runtime host loads the runtime into a process, creates the application domains within the process, and loads user code into the application domains.
The .NET Framework ships with a number of different runtime hosts, including the hosts listed in the following table:
Runtime Host Description
ASP.NET Loads the runtime into the process that is to handle the Web request.
ASP.NET also creates an application domain for each Web application that will run on a Web server.
Microsoft Internet Explorer
Creates application domains in which to run managed controls. The .NET Framework supports the download and execution of browser-based controls. The runtime interfaces with the extensibility mechanism of Microsoft Internet Explorer through a mime filter to create application domains in which to run the managed controls. By default, one application domain is created for each Web site.
Shell executables
Invokes runtime hosting code to transfer control to the runtime each time an executable is launched from the shell.
Garbage Collection
The .NET Framework's garbage collector manages the allocation and release of memory for your application.
Each time you use the new operator to create an object, the runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite.
Eventually the garbage collector must perform a collection in order to free some memory.
The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made.
When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory.
Automatic memory management is one of the services that the common language runtime provides during Managed Execution.
The common language runtime's garbage collector manages the allocation and release of memory for an application.
For developers, this means do not have to write code to perform memory management tasks when develop managed applications.
Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak, or attempting to access memory for an object that has already been freed.
Summary
.Net Framework: A common environment for building, deploying, and running Web Services and Web Applications.
Common Language Runtime (CLR): It provides a common runtime for all .NET languages.
Common Type System (CTS): It defines how types are declared, used, and managed in the runtime.
Common Language System (CLS): It specifies the interoperability or the ability to exchange and use information between .NET languages.
Application Domain: It is a logical and physical boundary created around every .NET application by CLR.
Runtime Host: It loads user code into the application domains.
Test Your Understanding
1. What are the components of .Net Framework? 2. What is the purpose of CLR?
3. What are main functions of CLR? 4. What is CTS?
5. What is CLS? 6. What is an Assembly?
7. What is an Application Domain? 8. What is Runtime Host?
9. What are types of Runtime Host in .Net Framework? 10. How many generations are there in GC?
Session 03: Introduction to C#
Learning Objectives
After completing the session, you will be able to:
Define Variables, statements, Identifiers, and Keywords of C# Explain the Console Application of C#
C# Variables, Identifiers and Keywords
Variables represent storage locations. Every variable has a type that determines the values that can be stored in the variable. C# is a type-safe language and the C# compiler guarantees that values stored in variables are always of the appropriate type.
C# defines seven categories of variables: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, and local variables. The following sample depicts each of these categories.
C# Variables: class A {
public static int x; int y;
void F(int[] v, int a, ref int b, out int c) { int i = 1;
c = a + b++; }
}
Where x is a static variable: A field declared with the static modifier. A static variable comes into existence before execution of the static constructor for its containing type, and ceases to exist when the associated application domain ceases to exist.
y is an instance variable: A field declared without the static modifier is called an instance
variable. An instance variable of a class comes into existence when a new instance of that class is created, and ceases to exist when there are no references to that instance and the instance's destructor (if any) has executed.
v[0] is an array element: The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance.
b is a reference parameter: A parameter declared with an ref modifier is an reference parameter.
c is an output parameter: A parameter declared with an out modifier is an output parameter.
And finally i is a local variable.
A local variable is declared by a local-variable-declaration, which may occur in a block, a for-statement, a switch-statement or a using-statement. The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it.
The types of the C# language are divided into two main categories: value types and reference types. A third category of types, pointers, is available only in unsafe code. Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to their data, the latter being known as objects. With
reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data and it is not possible for operations on one to affect the other.
C# Statements
Statements are program instructions and they are executed in sequence. C# has the following categories of statements:
S.No Category Purpose C# keywords
1. Selection statements
Causes the program control to be transferred to a specific flow based upon whether a certain condition is true or not.
if, else, switch, case
2. Iteration statements
You can create loops by using the iteration statements. Iteration statements cause embedded statements to be executed a number of times, subject to the loop-termination criteria. These statements are executed in order, except when a jump statement is encountered. do, for, foreach, in, while 3. Jump statements
Branching is performed using jump statements, which cause an immediate transfer of the program control.
break, continue, default, goto, return, yield 4. Exception handling statements
C# provides built-in support for handling anomalous situations, known as exceptions, which may occur during the execution of your program. These exceptions are handled by code that is outside the normal flow of control.
throw, catch, finally, try-catch-finally
S.No Category Purpose C# keywords 5. Checked
and unchecked
C# statements can execute in either checked or unchecked context. In a checked context, arithmetic overflow raises an exception. In an unchecked
context, arithmetic overflow is ignored and the result is truncated.
If neither checked nor unchecked is specified, the default context depends on external factors such as compiler options.
checked, unchecked
6. fixed Statement
The fixed statement prevents the garbage collector from relocating a movable variable. The fixed statement is only permitted in an unsafe context. Fixed can also be used to create fixed size buffers.
fixed
7. lock Statement
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock.
lock // statements_if_else.cs // if-else example using System; class IfTest {
static void Main() { Console.Write("Enter a character: "); char c = (char)Console.Read(); if (Char.IsLetter(c)) { if (Char.IsLower(c)) {
Console.WriteLine("The character is lowercase."); }
else {
Console.WriteLine("The character is uppercase."); }
} else {
Console.WriteLine("Not an alphabetic character."); }
} }
Iteration statements: // cs_foreach.cs class ForEachTest {
static void Main(string[] args) {
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray)
{ System.Console.WriteLine(i); } } } Jump statements: // statements_continue.cs using System; class ContinueTest {
static void Main() {
for (int i = 1; i <= 10; i++) { if (i < 9) { continue; } Console.WriteLine(i); } } }
Exception handling statements: // try_catch_finally.cs using System;
public class EHClass {
static void Main() {
try {
Console.WriteLine("Executing the try statement."); throw new NullReferenceException();
catch (NullReferenceException e) {
Console.WriteLine("{0} Caught exception #1.", e); } catch { Console.WriteLine("Caught exception #2."); } finally {
Console.WriteLine("Executing finally block."); }
} }
Checked and unchecked: // statements_checked.cs using System;
class OverFlowTest {
static short x = 32767; // Max short value static short y = 32767;
// Using a checked expression static int CheckedMethod() { int z = 0; try { z = checked((short)(x + y)); } catch (System.OverflowException e) { Console.WriteLine(e.ToString()); } return z; }
static void Main() {
Console.WriteLine("Checked output value is: {0}", CheckedMethod());
} }
fixed Statement:
// statements_fixed.cs // compile with: /unsafe using System; class Point { public int x, y; } class FixedTest {
// Unsafe method: takes a pointer to an int. unsafe static void SquarePtrParam (int* p) {
*p *= *p; }
unsafe static void Main() {
Point pt = new Point(); pt.x = 5;
pt.y = 6;
// Pin pt in place: fixed (int* p = &pt.x) { SquarePtrParam (p); } // pt now unpinned Console.WriteLine ("{0} {1}", pt.x, pt.y); } } lock Statement: // statements_lock.cs using System; using System.Threading; class ThreadTest {
public void RunMe() {
Console.WriteLine("RunMe called"); }
static void Main() {
ThreadTest b = new ThreadTest(); Thread t = new Thread(b.RunMe); t.Start();
} }
Identifiers
Identifiers are names used to denote variables, constants, types, methods, objects, and so on. An identifier begins with a letter or an underscore and ends with the character just before the next white space. C# identifiers are case sensitive. For example, the three variables hello, Hello, HELLO, are all different.
using System; namespace HelloApp {
class Program {
static void Main(string[] args) {
string Hello= "Hello"; string HELLO = "HELLO"; string hello= "hello";
Console.Write("Enter your Name: "); string name = Console.ReadLine(); Console.WriteLine(Hello+ " " + name); Console.WriteLine(HELLO + " " + name); Console.WriteLine(hello + " " + name); Console.ReadLine(); } } } Keywords
Keywords are predefined reserved identifiers that have special meanings to the compiler. They cannot be used as identifiers in your program unless they include @ as a prefix.
The following table provides the list of keywords in C#:
abstract event new struct
as explicit null switch
base extern object this
bool false operator throw
break finally out true
byte fixed override try
case float params typeof
catch for private uint
char foreach protected ulong
checked goto public unchecked
class if readonly unsafe
const implicit ref ushort
continue in return using
decimal int sbyte virtual
default interface sealed volatile
delegate internal short void
do is sizeof while
double lock stackalloc
else long static
enum namespace string
Console Applications
C# can be used to create applications that take input and display output at the command line console. These applications are ideal for learning C# development because the user interface is so simple. Console applications are also very useful for utility programs that require little or no user interaction. Example: using System; namespace HelloApp { class Program {
static void Main(string[] args) {
int intNum1 = 100; int intNum2 = 200;
Console.ReadLine(); } } } Summary Statements:
o Statements are program instructions. o Statements are executed in sequence.
Identifiers: Identifiers are names used to denote variables, constants, types, methods, objects, and so on.
Keywords:
o Keywords are special words built into the C# language and are reserved for specific use.
o Cannot use them for naming your classes, methods, and variables.
Variables: Variables represent storage locations. Every variable has a type that determines the values to be stored in the variable.
Console applications: C# can be used to create applications that take input and display output at the command line console.
Test Your Understanding
1. What are the types of statements and explain its syntax? 2. How do you give valid names in C#? Give some examples. 3. List some of the keywords in C#.
4. What is an Identifier?
Session 05: Data Types and Control Flow
Learning Objectives
After completing the session, you will be able to: Explain Data Types
Explain Boxing and Unboxing Define Operators
List various Control Flow Statements
Data Types
C# is a strongly typed language; therefore every variable and object must have a declared type. Some of the data types in C# are explained as follows:
Integer: It is denoted by the keyword int.
You can declare and initialize a variable of the type int like this: int intVar=534;
Members: Public Fields:
S.No Name Description
1 MaxValue Represents the largest possible value of an Int32. This field is constant. 2 MinValue Represents the smallest possible value of an Int32. This field is constant.
Public Methods:
S.No Name Description
1 CompareTo Overloaded. Compares this instance to a specified object or Int32 and returns an indication of their relative values.
2 Equals Overloaded. Returns a value indicating whether this instance is equal to a specified object or Int32.
3 GetHashCode Overridden. Returns the hash code for this instance.
4 GetType Gets the Type of the current instance. (Inherited from Object.) 5 GetTypeCode Returns the TypeCode for value type Int32.
6 Parse Overloaded. Converts the string representation of a number to its 32-bit signed integer equivalent.
Type Range Size .NET Framework type
int 2,147,483,648 to 2,147,483,647
S.No Name Description
7 ReferenceEquals Determines whether the specified. Object instances are the same instance. (Inherited from Object.)
8 ToString Overloaded. Overridden. Converts the numeric value of this instance to its equivalent string representation.
9 TryParse Overloaded. Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the operation succeeded.
Long integer: It is denoted by the keyword long.
You can declare and initialize a long variable like this: long longVar= 4294967296;
Double:The double keyword denotes a simple type that stores 64-bit floating-point values. The following table shows the precision and approximate range for the double type.
You can declare and initialize a double variable like this: double doubleVar=97432.343;
Or
double doubleVar=97432.343d; In the earlier statement, the suffix d is optional.
Members: Public Fields:
S.No Name Description
1 MaxValue Represents the largest possible value of a Double. This field is constant. 2 MinValue Represents the smallest possible value of a Double. This field is constant. 3 Epsilon Represents the smallest positive Double greater than zero. This field is
constant.
4 NaN Represents a value that is not a number (NaN). This field is constant. 5 NegativeInfinity Represents negative infinity. This field is constant.
6 PositiveInfinity Represents positive infinity. This field is constant.
Type Range Size .NET Framework type
long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Signed 64-bit integer
System.Int64
Type Approximate Range Precision .NET Framework type double ±5.0 × 10−324 to ±1.7 × 10308 15-16 digits System. Double
Public Methods:
S.No Name Description
1 CompareTo Overloaded. Compares this instance to a specified object or Double and returns an indication of their relative values. 2 Equals Overloaded. Returns a value indicating whether this instance is
equal to a specified object or Double.
3 GetHashCode Overridden. Returns the hash code for this instance.
4 GetType Gets the Type of the current instance. (Inherited from Object.) 5 GetTypeCode Returns the TypeCode for value type Double.
6 IsInfinity Returns a value indicating whether the specified number evaluates to negative or positive infinity
7 IsNaN Returns a value indicating whether the specified number evaluates to a value that is not a number (NaN).
8 IsNegativeInfinity Returns a value indicating whether the specified number evaluates to negative infinity.
9 IsPositiveInfinity Returns a value indicating whether the specified number evaluates to positive infinity.
10 Parse Overloaded. Converts the string representation of a number to its double-precision floating point number equivalent
11 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object)
12 ToString Overloaded. Overridden. Converts the numeric value of this instance to its equivalent string representation.
13 TryParse Overloaded. Converts the string representation of a number to its double-precision floating-point number equivalent. A return value indicates whether the conversion succeeded or failed.
Char: The char keyword is used to declare a Unicode character in the range indicated in the following table. Unicode characters are 16-bit characters used to represent most of the known written languages throughout the world.
You can declare and initialize a char variable like this: char charVar = ’a’;
Members: Public Fields:
S.No Name Description
1 MaxValue Represents the largest possible value of a char. This field is constant. 2 MinValue Represents the smallest possible value of a char. This field is constant.
Type Range Size .NET Framework type
Public Methods:
S.No Name Description
1 CompareTo Overloaded. Compares this instance to a specified object or value type, and returns an indication of their relative values. 2 ConvertFromUtf32 Converts the specified Unicode code point into a UTF-16
encoded string.
3 ConvertUtf32 Overloaded. Converts the value of a UTF-16 encoded surrogate pair into a Unicode code point.
4 Equals Overloaded.
4 GetHashCode Overridden. Returns the hash code for this instance.
5 GetNumericValue Overloaded. Converts a specified numeric Unicode character to a double-precision floating point number.
6 GetType Gets the Type of the current instance. (Inherited from Object) 7 GetTypeCode Returns the TypeCodefor value type Char.
8 GetUnicodeCategory Overloaded. Categorizes a Unicode character into a group identified by one of the UnicodeCategory values.
9 IsControl Overloaded. Indicates whether a specified Unicode character is categorized as a control character.
10 IsDigit Overloaded. Indicates whether a Unicode character is categorized as a decimal digit.
11 IsHighSurrogate Overloaded. Indicates whether the specified Char object is a high surrogate.
12 IsLetter Overloaded. Indicates whether a Unicode character is categorized as an alphabetic letter.
13 IsSurrogatePair Overloaded. Indicates whether two specified Char objects form a surrogate pair.
14 IsSymbol Overloaded. Indicates whether a Unicode character is categorized as a symbol character.
15 IsUpper Overloaded. Indicates whether a Unicode character is categorized as an uppercase letter.
16 IsWhiteSpace Overloaded. Indicates whether a Unicode character is categorized as white space.
17 Parse Converts the value of the specified string to its equivalent Unicode character.
18 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)
19 ToLower Overloaded. Converts the value of a Unicode character to its lowercase equivalent.
20 TolowerInvariant Converts the value of a Unicode character to its lowercase equivalent using the casing rules of the invariant culture. 21 ToString Overloaded. Overridden. Converts the value of this instance to
S.No Name Description
22 ToUpper Overloaded. Converts the value of a Unicode character to its uppercase equivalent.
23 ToUpperInvariant Converts the value of a Unicode character to its uppercase equivalent using the casing rules of the invariant culture. 24 TryParse Converts the value of the specified string to its equivalent
Unicode character. A return code indicates whether the conversion succeeded or failed.
String: The string type represents a string of unicode characters.
You can declare and initialize a string variable like this: string strVar=”Welcome”;
Members: Public Fields:
S.No Name Description
1 Empty Represents the empty String. This field is read only.
Public Properties:
S.No Name Description
1 Chars Gets the character at a specified character position in this instance. 2 Length Gets the number of characters in this instance.
Public Methods:
S.No Name Description
1 Clone Returns a reference to this instance of String.
2 Compare Overloaded. Compares two specified String objects.
3 CompareOrdinal Overloaded. Compares two String objects by evaluating the numeric values of the corresponding Char objects in each string. 4 CompareTo Overloaded. Compares this instance with a specified object or
String and returns an indication of their relative values.
5 Concat . Overloaded. Concatenates one or more instances of String, or the String representations of the values of one or more instances of Object.
6 Contains Returns a value indicating whether the specified String object occurs within this string.
7 Copy Creates a new instance of String with the same value as a specified String.
8 CopyTo Copies a specified number of characters from a specified position in this instance to a specified position in an array of Unicode characters.
S.No Name Description
9 EndsWith Overloaded. Determines whether the end of an instance of String matches a specified string.
10 Equals Overloaded. Overridden. Determines whether two String objects have the same value.
11 Format Overloaded. Replaces each format item in a specified String with the text equivalent of a corresponding object's value.
12 GetEnumerator Retrieves an object that can iterate through the individual characters in this string.
13 GetHashCode Overridden. Returns the hash code for this string.
14 GetType Gets the Type of the current instance. (Inherited from Object.)
15 GetTypeCode Returns the TypeCode for class String.
16 IndexOf Overloaded. Reports the index of the first occurrence of a String, or one or more characters, within this string.
17 IndexOfAny Overloaded. Reports the index of the first occurrence in this instance of any character in a specified array of Unicode characters.
18 Insert Inserts a specified instance of String at a specified index position in this instance.
19 Intern Retrieves the system's reference to the specified String.
20 IsInterned Retrieves a reference to a specified String.
21 IsNormalized Overloaded. Indicates whether this string is in a particular Unicode normalization form.
22 IsNullorEmpty Indicates whether the specified String object is a null reference (Nothing in Visual Basic) or an Empty string.
23 Join Overloaded. Concatenates a specified separator String between each element of a specified String array, yielding a single concatenated string.
24 LastIndexOf Overloaded. Reports the index position of the last occurrence of a specified Unicode character or String within this instance. 25 LastIndexOfAny Overloaded. Reports the index position of the last occurrence in
this instance of one or more characters specified in a Unicode array.
26 Normalize Overloaded. Returns a new string whose binary representation is in a particular Unicode normalization form.
27 Op_Equality Determines whether two specified String objects have the same value.
28 Op_InEquality Determines whether two specified String objects have different values.
S.No Name Description
29 PadLeft Overloaded. Right-aligns the characters in this instance, padding on the left with spaces or a specified Unicode character for a specified total length.
30 PadRight Overloaded. Left-aligns the characters in this string, padding on the right with spaces or a specified Unicode character, for a specified total length.
31 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)
32 Remove Overloaded. Deletes a specified number of characters from this instance.
33 Replace Overloaded. Replaces all occurrences of a specified Unicode character or String in this instance, with another specified Unicode character or String.
34 Split Overloaded. Returns a String array containing the substrings in this instance that are delimited by elements of a specified Char or String array.
35 StartsWith Overloaded. Determines whether the beginning of an instance of String matches a specified string.
36 SubString Overloaded. Retrieves a substring from this instance.
37 ToCharArray Overloaded. Copies the characters in this instance to a Unicode character array.
38 ToLower Overloaded. Returns a copy of this String converted to lowercase.
39 ToLowerInvariant Returns a copy of this String object converted to lowercase using the casing rules of the invariant culture.
40 ToString Overloaded. Overridden. Converts the value of this instance to a String.
41 ToUpper Overloaded. Returns a copy of this String converted to uppercase.
42 ToUpperInvariant Returns a copy of this String object converted to uppercase using the casing rules of the invariant culture.
43 Trim Overloaded. Removes all occurrences of a set of specified characters from the beginning and end of this instance. 44 TrimEnd Removes all occurrences of a set of characters specified in an
array from the end of this instance.
45 TrimStart Removes all occurrences of a set of characters specified in an array from the beginning of this instance.
Apart from the above primitive data types, C# also provides user-defined value types, enums and structs. Here is a simple example of declaring a value type variable
// declares a variable of int type int iPointX;
bool bChecked = true;
Reference Types
Instances of classes are reference types. Reference types are allocated on the heap. In C#, all classes are derived from the .NET Framework class Object within the System namespace. C# does not support pointers directly (though we can use them using unsafe code), but classes, being reference data types, act like pointers. If you copy a pointer to another pointer, then they both still refer the same object. Thus if you pass an instance of a class to a method, changes made to the object passed in will persist upon returning from the method call.
As mentioned previously, reference types are allocated on the heap. The new keyword is used to allocate a new instance of a reference type (class).You do not need to free an instance of a class in C#, however. The CLR does garbage collection on object instances that are no longer
referenced. Here is a simple example of instantiating an object of a class:
// Class is instantiated here using the new keyword. A new object // of type SomeClass will be allocated on the heap.
SomeClass instance = new SomeClass();
Boxing and UnBoxing
Boxing and unboxing are the processes that enable value types (for example, integers) to be treated as reference types (objects). The value is "boxed" inside an object and subsequently "unboxed" back to a value type.
Boxing Is Implicit
Boxing is an implicit conversion of a value type to the type Object. Boxing a value allocates an instance of Object and copies the value into the new object instance. When you provide a value type where a reference is expected and the value is implicitly boxed. For example, if you assign a primitive type such as an integer to a variable of type Object (which is legal because int derives from Object) the value is boxed,
int i = 123; object o = i;
The result of this statement is creating an object o, on the stack, that references a value of the type int, on the heap. This value is a copy of the value-type value assigned to the variable i.
Example:
class TestBoxing {
static void Main() {
int i = 123;
object o = i; // implicit boxing
i = 456; // change the contents of i
System.Console.WriteLine("The value-type value = {0}", i); System.Console.WriteLine("The object-type value = {0}", o); }
}
Unboxing Must Be Explicit
Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. An unboxing operation consists of:
1. Checking the object instance to make sure it is a boxed value of the given value type. 2. Copying the value from the instance into the value-type variable.
The following statements demonstrate both boxing and unboxing operations: int i = 123; // A value type
object box = i; // Boxing int j = (int)box; // Unboxing
For an unboxing conversion to a given value type to succeed at run time, the value of the source argument must be a reference to an object that was previously created by boxing a value of that value type. If the source argument is null or a reference to an incompatible object, an
InvalidCastException is thrown.
Example:
class TestUnboxing {
static void Main() {
int i = 123;
object o = i; // implicit boxing
try {
int j = (short) o; // attempt to unbox
}
catch (System.InvalidCastException e) {
System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
} } }
Operators
C# has a number of standard operators, taken from C, C++ and Java. Most of these should be quite familiar to programmers and the less common ones are covered here. The operators can be broadly classified as Primary, Unary, Type operators, Arithmetic, Relational, and Logical. The following table lists the standard operators with a syntax sample:
S.No Operator Category Operators 1 Arithmetic + , - , * , / , %
2 Logical & | ^ ! ~ && || true false 3 String Concatenation + 4 Increment, Decrement ++ , -- 5 Shift << >> 6 Relational == != < > <= >= 7 Assignment = += -= *-= /-= %-= &-= |-= ^-= <<-= >>-= ?? 8 Member access . 9 Indexing [ ] 10 Cast () 11 Conditional ?: 12 Delegate Concatenation and Removal + , -
13 Object creation new
14 Type information as , is , Typeof() , sizeof() 16 Indirection and
Address
* , -> , [ ] , &
Note that while writing classes it is possible to change the default behavior of some of these operators, although this should only be done where the resultant semantics makes sense. The earlier table also indicates which of the operators are overloadable.
Operator precedence and their associability:
When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the binary + operator.
The following table summarizes all operators in order of precedence from highest to lowest:
Category Operators Associability
Primary x.y f(x) a[x] x++ x-- new typeof checked unchecked Left Unary + - ! ~ ++x --x (T)x Left Multiplicative * / % Left Additive + - Left Shift << >> Left Relational and type testing < > <= >= is as Left Equality == != Right
Logical AND & Left
Logical XOR ^ Left
Logical OR | Left
Conditional AND && Left
Conditional OR || Left
Conditional ?: Right
Assignment = *= /= %= += -= <<= >>= &= ^= |=
Right
When an operand occurs between two operators with the same precedence, the associability of the operators controls the order in which the operations are performed:
Except for the assignment operators, all binary operators are left-associative, meaning that operations are performed from left to right. For example, x + y + z is evaluated as (x + y) + z.
The assignment operators and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. For example, x = y = z is evaluated as x = (y = z).
Precedence and associability can be controlled using parentheses. For example, x + y * z first multiplies y by z and then adds the result to x, but (x + y) * z first adds x and y and then multiplies the result by z.
Overloadable Operators:
C# allows user-defined types to overload operators by defining static member functions using the operator keyword. Not all operators can be overloaded, however, and others have restrictions, as listed in this table:
S.No Operators Overloadability
1 +, , !, ~, ++, --, true, false
These unary operators can be overloaded.
2 +, -, *, /, %, &, |, ^, <<, >>
These binary operators can be overloaded.
3 ==, !=, <, >, <=, >=
The comparison operators can be overloaded
4 &&, || The conditional logical operators cannot be overloaded, but they are evaluated using & and |, which can be overloaded.
5 [ ] The array indexing operator cannot be overloaded, but you can define indexers.
6 () The cast operator cannot be overloaded, but you can define new conversion operators (see explicit and implicit).
7 +=, -=, *=, /=, %=, &=, |=, ^=,
<<=, >>=
Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded.
8 =, ., ?:, ->, new, is, sizeof, typeof
These operators cannot be overloaded.
Control Flow
Control flow statements control the execution path of the program.
The following table lists the Control flow statements: S.No Category C# keywords
1 Selection statements if, else, switch, case 2 Iteration statements do, for, foreach,, while 3 Jump statements break, continue, goto,
return, throw
Selection Statements--If else:
The if statement selects a statement for execution based on the value of a Boolean expression.
Example: // statements_if_else.cs // if-else example using System; class IfTest {
{ Console.Write("Enter a character: "); char c = (char)Console.Read(); if (Char.IsLetter(c)) { if (Char.IsLower(c)) {
Console.WriteLine("The character is lowercase."); }
else {
Console.WriteLine("The character is uppercase."); }
} else {
Console.WriteLine("Not an alphabetic character."); }
} }
Switch case:
The switch statement is a control statement that handles multiple selections and enumerations by passing control to one of the case statements within its body
Example:
// statements_switch.cs using System;
class SwitchTest {
static void Main() {
Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large"); Console.Write("Please enter your selection: ");
string s = Console.ReadLine(); int n = int.Parse(s); int cost = 0; switch(n) { case 1: cost += 25; break; case 2: cost += 25;
goto case 1; case 3:
cost += 50; goto case 1; default:
Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
break; }
if (cost != 0) {
Console.WriteLine("Please insert {0} cents.", cost); }
Console.WriteLine("Thank you for your business."); }
}
Iteration Statements--do:
The do statement executes a statement or a block of statements enclosed in {} repeatedly until a specified expression evaluates to false.
Example:
// statements_do.cs using System;
public class TestDoWhile {
public static void Main () { int x = 0; do { Console.WriteLine(x); x++; } while (x < 5); } } for:
The for loop executes a statement or a block of statements repeatedly until a specified expression evaluates to false. The for loop is handy for iterating over arrays and for sequential processing. In the following example, the value of int i is written to the console and i is incremented each time through the loop by 1.
Example: // statements_for.cs // for loop using System; class ForLoopTest {
static void Main() {
for (int i = 1; i <= 5; i++) { Console.WriteLine(i); } } } foreach;
The foreach statement repeats a group of embedded statements for each element in an array or an object collection. The foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects.
Example:
// cs_foreach.cs class ForEachTest {
static void Main(string[] args) {
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray)
{ System.Console.WriteLine(i); } } } while:
The while statement executes a statement or a block of statements until a specified expression evaluates to false. Example: // statements_while.cs using System; class WhileTest {
static void Main() { int n = 1; while (n < 6) { Console.WriteLine("Current value of n is {0}", n); n++; } } } Jump Statements—break:
The break statement terminates the closest enclosing loop or switch statement in which it appears. Control is passed to the statement that follows the terminated statement, if any.
Example:
// statements_break.cs using System;
class BreakTest {
static void Main() {
for (int i = 1; i <= 100; i++) { if (i == 5) { break; } Console.WriteLine(i); } } } continue:
The continue statement passes control to the next iteration of the enclosing iteration statement in which it appears. Example: // statements_continue.cs using System; class ContinueTest {
static void Main() {
for (int i = 1; i <= 10; i++) { if (i < 9) { continue; } Console.WriteLine(i); } } } goto:
The goto statement transfers the program control directly to a labeled statement.
Example:
// statements_goto_switch.cs using System;
class SwitchTest {
static void Main() {
Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large"); Console.Write("Please enter your selection: ");
string s = Console.ReadLine(); int n = int.Parse(s); int cost = 0; switch (n) { case 1: cost += 25; break; case 2: cost += 25; goto case 1; case 3: cost += 50; goto case 1; default: Console.WriteLine("Invalid selection."); break; } if (cost != 0) {
Console.WriteLine("Please insert {0} cents.", cost); }
Console.WriteLine("Thank you for your business."); }
}
return:
The return statement terminates execution of the method in which it appears and returns control to the calling method. It can also return an optional value. If the method is a void type, the return statement can be omitted.
Example:
// statements_return.cs using System;
class ReturnTest {
static double CalculateArea(int r) {
double area = r * r * Math.PI; return area;
}
static void Main() { int radius = 5; Console.WriteLine("The area is {0:0.00}", CalculateArea(radius)); } } throw:
The throw statement is used to signal the occurrence of an anomalous situation (exception) during the program execution.
Example:
// throw example using System;
public class ThrowTest {
static void Main() {
string s = null;
{
throw new ArgumentNullException(); }
Console.Write("The string s is null"); // not executed }
}
Summary
Data types: It is the basic building block of any language. It can be of two types: Build-In Data Type
User-Defined Data Type
Boxing: Converting value type to reference type is called Boxing. Following are the two types of boxing:
Implicit Boxing Explicit Boxing
Unboxing: Converting reference type to value type is called Unboxing.
Operators: The symbol representing the operations to be performed in an expression.
Control Flow Statements: It controls the execution path of the program. It can be of following types:
Selection statements Iteration statements Jump statements
Test your Understanding
1. What are the primitive data types in C#? 2. State the difference between char and string.
3. What is the difference between floating point and decimal type? 4. Differentiate between implicit and explicit casting.
5. What is boxing and unboxing?
6. What are the different types of control flow statements? 7. What is the use of checked and unchecked statements?
Session 08: Arrays, Methods and Parameters
Learning Objectives
After completing this session, you will be able to: Define Arrays and its types
Explain Methods and how to call C# methods
Identify Parameters and different ways of passing parameters Describe the overview of method overloading
Arrays
An array is an indexed collection of objects, all of the same type. C# arrays are somewhat different from arrays in C++ and other languages—because they are objects. This provides them with built-in support like useful methods and properties. There are three types of arrays:
One-dimensional arrays
Multidimensional arrays rectangular arrays, Multidimensional jagged arrays
Declaring an array:
C# provides native syntax for the declaration of Array objects: int[] myIntArray;
What is actually created, however, is an object of type System.Array. Arrays in C# thus provide you with the best of both worlds: easy-to-use C-style syntax underpinned with an actual class definition so that instances of an array have access to the methods and properties of
System.Array.
Once an array is declared, it must also be instantiated using the new keyword. The following declaration sets aside memory for an array holding five integers:
int[] myIntArray = new int[5];
When an array is created for value types, each element initially contains the default value for the type stored in the array. In the earlier example, each of those array elements is initialized to 0, the default value for integer types. With an array of reference types, the elements are not initialized to their default values. Instead, they are initialized to null.
Arrays are zero-based, which means that the index of the first element is always zero — in this case, myArray[0].
As arrays are objects, they have properties. One of the more useful properties of the Array class is Length, which tells how many objects are in an array.
for (int i = 0;i<5;i++) {
empArray[i] = i; }
for (int i = 0;i<empArray.Length;i++) {
MessageBox.Show(empArray[i]); }
Initializing Array Elements:
Rather than assigning elements to the array as you have done so far, it is possible to initialize the contents of an array at the time it is instantiated by providing a list of values delimited by curly braces ({}). C# provides two different syntaxes to accomplish the same task:
int[] myIntArray = new int[5] { 2, 4, 6, 8, 10 };
int[] myIntArray = { 2, 4, 6, 8, 10 };
Multidimensional Rectangular Arrays:
A rectangular array is an array of two (or more) dimensions. In the classic two-dimensional array, the first dimension is the number of rows and the second dimension is the number of columns. To declare and instantiate a two-dimensional rectangular array named myRectangularArray that contains two rows and three columns of integers,
int [,] myRectangularArray = new int[2,3];
for (int i = 0;i < rows;i++) {
for (int j = 0;j<columns;j++) {
rectangularArray[i,j] = i+j; }
}
The brackets in the int[,] declaration indicate that the type is an array of integers, and the single comma indicates the array has two dimensions; two commas would indicate three dimensions, and so on. Just as you can initialize a one-dimensional array using bracketed lists of values, you can initialize a two-dimensional array using a similar syntax.
//this is a 4x3 array (four rows by three columns) int[,] rectangularArray =
{
{0,1,2}, {3,4,5}, {6,7,8}, {9,10,11} };