- •Foreword
- •About Programmer’s Heaven
- •About Faraz Rasheed
- •Contents In Summary
- •Tools of the trade
- •The C# Language
- •The .Net Architecture and .Net Framework
- •The Common Language Runtime (CLR)
- •MSIL (Microsoft Intermediate Language) Code
- •Just In Time Compilers (JITers)
- •The Framework Class Library (FCL)
- •The Common Language Specification (CLS)
- •The Common Type System (CTS)
- •Garbage Collection (GC)
- •The .Net Framework
- •C# compared to C++
- •The Visual Studio.Net IDE
- •Projects and Solutions
- •Toolbox, Properties and Class View Tabs
- •Writing Your First Hello World Console Application in C#
- •Working Without Visual Studio.Net
- •With Visual Studio.Net
- •Understanding the Hello World Application Code:
- •Namespaces in C#
- •The using Keyword
- •The class Keyword
- •The Main() Method
- •Printing on the Console
- •Comments
- •Important points to remember
- •A more interactive Hello World Application
- •Discussing a more interactive Hello World Application
- •2. C# Language Fundamentals
- •Lesson Plan
- •Basic Data Types and their mapping to CTS (Common Type System)
- •Integral Types
- •Floating Point Types
- •Other Types
- •Variables
- •Constant Variables or Symbols
- •Naming Conventions for variables and methods
- •Operators in C#
- •Arithmetic Operators
- •Operand
- •Prefix and Postfix notation
- •Assignment Operators
- •Operand
- •Relational Operators
- •Operand
- •Operand
- •Other Operators
- •Operand
- •Operator Precedence
- •Flow Control And Conditional Statements
- •The if...else statement
- •The switch...case statement
- •Loops In C#
- •The for Loop
- •Some important points about the for loop
- •The do...while Loop
- •while Loop
- •Arrays in C#
- •Array Declaration
- •Accessing the values stored in an array
- •foreach Loop
- •3. Classes and Objects
- •Lesson Plan
- •Concept of a Class
- •Objects
- •Fields
- •Data Type
- •Methods
- •Instantiating the class
- •Accessing the members of a class
- •Access Modifiers or Accessibility Levels
- •Access Modifier
- •Properties
- •Using Properties
- •Precautions when using properties
- •Static Members of the class
- •Some More about Methods
- •Constructors
- •Finalize() Method of Object class
- •Destructors
- •Method and Constructor Overloading
- •Overloading Constructors
- •Value types (out & ref Keywords)
- •Reference types
- •Some more about references and objects
- •4. Inheritance & Polymorphism
- •Lesson Plan
- •Inheritance
- •Inheritance in C#
- •Implementing inheritance in C#
- •Constructor calls in Inheritance
- •The base keyword - Calling Constructors of the base-class explicitly
- •Protected Access Modifier
- •The Protected internal Access Modifier
- •The sealed keyword
- •Object class - the base of all classes
- •Polymorphism
- •Using the reference of the base type for referencing the objects of child types
- •Using methods with the same name in the Base and the Sub-class
- •Overriding the methods - virtual and override keywords
- •The new keyword
- •Type casting the objects - Up-casting and Down-casting
- •The is and as keywords
- •Boxing and Un-boxing
- •5. Structures, Enumeration, Garbage Collection & Nested Classes
- •Lesson Plan
- •Structures (struct)
- •Defining a struct
- •Instantiating the struct
- •structs as Value Types
- •Enumeration
- •The Need for Enumeration
- •Using Enumeration (enum)
- •More about Enumerations
- •Garbage Collection in .Net
- •Destructors and Performance Overhead
- •System.GC.Collect() method
- •Nested Classes in C#
- •6. Abstract Classes & Interfaces
- •Lesson Plan
- •Abstract Classes
- •Interfaces
- •Implementing More Than One Interface
- •Explicit implementation of methods
- •Casting to an interface using is and as operators
- •An interface inheriting one or more interfaces
- •7. Arrays, Collections & String Manipulation
- •Lesson Plan
- •Arrays Revisited
- •Multidimensional Arrays
- •Instantiating and accessing the elements of multidimensional arrays
- •Instantiating and accessing Jagged Arrays
- •Some other important points about multidimensional arrays
- •The foreach Loop
- •Collections
- •The ArrayList class
- •The Stack class
- •The Queue class
- •Dictionaries
- •The Hashtable class
- •Constructing a Hashtable
- •Adding items to a Hashtable
- •Retrieving items from the Hashtable
- •Removing a particular item
- •Getting the collection of keys and values
- •Checking for the existence of a particular item in a hashtable
- •The SortedList class
- •String Handling in C#
- •The string class and its members
- •The StringBuilder class
- •8. Exception Handling
- •Lesson Plan
- •Exceptions Basics
- •The need for Exceptions
- •Exceptions in C# and .Net
- •Handling Exceptions using the try...catch...finally blocks
- •Use of the try...catch block
- •Exception class' Message and StackTrace Properties
- •The finally block
- •Catching Multiple Exceptions using multiple catch blocks
- •An important point to remember in multiple catch blocks
- •Other important points about Exception Handling in C#
- •Defining your own custom exceptions
- •Exception Hierarchy in the .Net Framework
- •Throwing an exception: the throw keyword
- •9. Delegates & Events
- •Lesson Plan
- •Delegates Basics
- •The type or signature of the method the delegate can point to
- •The delegate reference, that can be used to reference a method
- •3.The actual method referenced by the delegate
- •Calling the actual method through its delegate
- •Confusion in terminology
- •Delegates in the .Net Framework
- •Passing delegates to methods
- •Multicast Delegates
- •Implementing a Multicast Delegate
- •Removing a method from the multicast delegate's invocation list
- •Events and Event Handling
- •Event Handling in C#
- •A Clock Timer Example
- •Multicast events
- •Passing some data with the Event: Sub-classing System.EventArgs
- •10. WinForms & Windows Applications
- •Lesson Plan
- •Windows Applications and .Net
- •WinForm Basics
- •Building the "Hello WinForm" Application
- •Understanding the Code
- •Adding Event Handling
- •Visual Studio.Net & its IDE (Integrated Development Environment)
- •IntelliSense and Hot Compiler
- •Code Folding
- •Integrated Compiler, Solution builder and Debugger
- •Form Designer
- •Solution Explorer
- •Menus in the Visual Studio .Net IDE
- •Using Visual Studio.Net to build the "Hello WinForm" Application
- •Creating a new Project
- •Setting various properties of the form
- •Adding Controls to the Form
- •Adding Event Handling
- •Executing the application
- •The code generated by the Form Designer
- •Using More Controls
- •Using various controls in an application: Programmer's Shopping Cart
- •Designing the form and placing the controls
- •Writing Code for Event Handling
- •Some Important Points for designing Windows Applications
- •11. More Windows Controls & Standard Dialog Boxes
- •Lesson Plan
- •Collection Controls
- •List Box Control
- •Adding items to the list box
- •Accessing items in the list box
- •Removing items from the list box
- •List Box Events
- •Combo Box Control
- •Tree View
- •The TreeNode Editor
- •Adding/Removing items at runtime
- •Tree View Events
- •Image List Control
- •Attaching An Image List to different controls
- •List View Control
- •Two Image Lists in the List View Control
- •Adding items to the list view control using designer
- •Adding Items at runtime using code
- •Events for List View Control
- •Main Menu
- •Tool Bar
- •Date Time Picker
- •Windows Standard Dialog Boxes
- •Open File Dialog Box
- •Using the Open File Dialog Box
- •Save File Dialog Box
- •Font and Color Dialog Boxes
- •12. Data Access using ADO.Net
- •Lesson Plan
- •Introducing ADO.Net
- •Different components of ADO.Net
- •A review of basic SQL queries
- •SQL SELECT Statement
- •SQL INSERT Statement
- •SQL UPDATE Statement
- •SQL DELETE Statement
- •Performing common data access tasks with ADO.Net
- •Accessing Data using ADO.Net
- •Defining the connection string
- •Defining a Connection
- •Defining the command or command string
- •Defining the Data Adapter
- •Creating and filling the DataSet
- •A Demonstration Application
- •Loading tables
- •Filling the controls on the Form
- •Navigating through the records
- •Updating the table
- •Building the Application
- •Loading the table and displaying data in the form's controls
- •Initialing Commands
- •Adding Parameters to the commands
- •The ToggleControls() method of our application
- •Editing (or Updating) Records
- •Event Handler for the Save Button
- •Event Handler for the Cancel Button
- •Inserting Records
- •Deleting a Record
- •Using Stored Procedures
- •Sample Stored Procedures
- •UPDATE Stored Procedure
- •INSERT Stored Procedure
- •DELETE Stored Procedure
- •SELECT Stored Procedure
- •Using Stored Procedures with ADO.Net in C#
- •The modified InitializeCommands() method
- •Using Data Grid Control to View .Net data
- •A Demonstration Application for Data Grid Control
- •Second Demonstration - Using multiple related tables
- •Retrieving data using the SELECT command
- •Updating Records using INSERT, UPDATE and DELETE commands
- •13. Multithreading
- •Lesson Plan
- •What is Multithreading
- •Multithreading in C#
- •Thread Functionality
- •Static members of the System.Threading.Thread class
- •Instance members of the System.Threaing.Thread class
- •Thread Demonstration Example - Basic Operations
- •Thread Demonstration Example - Thread Priority
- •Thread Demonstration Example - Thread Execution Control
- •Using Join() to wait for running threads
- •Thread Synchronization
- •The C# Locking Mechanism
- •Threads may cause Deadlock
- •14. The File System & Streams
- •Lesson Plan
- •Working with the File System
- •Obtaining the Application’s Environment Information – The System.Environment class
- •Demonstration Application – Environment Information
- •Obtaining the paths of various Windows Standard folders – Environment.GetFolderPath()
- •Manipulating Files using System.IO.File and System.IO.FileInfo classes
- •System.IO.File class
- •Creating a file using Create() method
- •Copying and Moving a file using Copy() and Move() methods
- •Checking the existence of the file using Exists() method
- •Getting Attributes of a file using GetAttributes() method
- •System.IO.FileInfo class
- •A quick and simple example
- •Manipulating Directories (folders) using System.IO.Directory and System.IO.DirectoryInfo classes
- •System.IO.Directory class
- •Creating, deleting and checking for the existence of directories
- •Getting the contents (files and sub-directories) of a directory
- •System.IO.DirectoryInfo class
- •Demonstration application for the DirectoryInfo class
- •Streams
- •An overview of the different types of streams
- •The System.Stream class – the base of all streams in the .Net framework
- •Different types of file streams – Reading and Writing to files
- •Using System.IO.FileStream to read and write data to files
- •A string representing the path and name of the file
- •Opening and reading from a file
- •Using BinaryReader and BinaryWriter to read and write primitives to files
- •Using StreamReader and StreamWriter to read and write text files
- •Serialization and De-serialization
- •Implementing Serialization and Deserialization – A simple example
- •Formatters in Serialization
- •Preventing certain elements from Serializing – The [NonSerialized] attribute
- •Getting notified when Deserializing - the IDeserializationCallBack interface
- •Asynchronous Reading and Writing with Streams
- •A demonstration application
- •Issues Regarding Asynchronous Read/Write
- •Important points regarding the use of Streams
- •15. New Features In C# 2.0
- •C# evolves
- •The need for generics
- •Generic collections
- •Creating generic types
- •Constraining type parameters
- •Final thoughts on generics
- •Partial types
- •Nullable types
- •Anonymous methods in event handling
- •Adventures with anonymous methods
- •Final thoughts on C# 2.0
- •16. The Road Ahead
- •Learning More
- •Getting Help
- •Book.revision++
- •Good Luck!
Programmers Heaven: C# School
You can use & and | operators in place of && and || but for combining conditional expressions, && and || are more efficient because they use "short circuit evaluation". For example, if in the expression (i>3 && j<10), i>3 evaluates to false, the second expression j<10 won't be checked and false will be returned (when using AND, if one of the participant operands is false, the whole operation will result in false). Hence, one should be very careful when using assignment expressions with && and || operators. The & and | operators don't do short circuit evaluation and do execute all the comparisons before returning the result.
Other Operators
There are some other operators present in C#. A short description of these is given below:
Operand |
Description |
<< |
Left shift bitwise operator |
>> |
Right shift bitwise operator |
. |
Member access for objects |
[] |
Index operator used in arrays and collections |
() |
Cast operator |
?: |
Ternary operator |
Operator Precedence
All operators are not treated equally. There is a concept of "operator precedence" in C#. For example:
int i = 2 + 3 * 6;
// i would be 20 not 30
3 will be multiplied by 6 first then the result will be added to 2. This is because the multiplication operator * has precedence over the addition operator +. For a complete table of operator precedence, consult MSDN or the .Net framework documentation.
Flow Control And Conditional Statements
The if...else statement
Condition checking has always been the most important construct in any language right from the time of the assembly language days. C# provides conditional statements in the form of the if...else statement. The structure of this statement is:
if(Boolean expression)
Statement or block of statements
else
Statement or block of statements
39
Programmers Heaven: C# School
The else clause above is optional. A typical example is:
if(i==5)
Console.WriteLine("Thank God, I finally became 5.");
In the above example, the console message will be printed only if the expression i==5 evaluates to true. If you would like to take some action when the condition does not evaluate to true, then you can use else clause:
if(i==5)
Console.WriteLine ("Thank God, I finally became 5.");
else
Console.WriteLine("Missed...When will I become 5?");
Only the first message will be printed if i is equal to 5. In any other case (when i is not 5), the second message will be printed. If you want to use a block of statements (more than one statement) under if or else, you can enclose your block in {} brackets:
if(i==5)
{
j = i*2;
Console.WriteLine("Thank God, I finally became 5.");
}
else
{
j = i/2;
Console.WriteLine("Missed...When will I become 5?");
}
I would always recommend to use { } brackets to enclose the statements following if and else even if you only have a single statement. It increases readability and prevents many bugs that otherwise can result if you neglect the scope of if and else statements.
You can also have if after else for further conditioning:
if(i==5) |
// line 1 |
{ |
|
Console.WriteLine("Thank God, I finally became 5.");
}
else if(i==6) // line 5
{
Console.WriteLine("Ok, 6 is close to 5.");
}
40
Programmers Heaven: C# School
else |
// line 9 |
{
Console.WriteLine("Missed...When will I become 5 or be close to 5?");
}
Here else if(i==6) is executed only if the first condition i==5 is false, and else at line 9 will be executed only if the second condition i==6 (line 5) executes and fails (that is, both the first and second conditions fail). The point here is else at line 9 is related to if on line 5.
Since if...else is also a statement, you can use it under other if...else statement (nesting), like:
if(i>5) |
// |
line |
1 |
{ |
|
|
|
if(i==6) |
// |
line |
3 |
{ |
|
|
|
Console.WriteLine("Ok, 6 is close to 5.");
}
else // line 7
{
Console.WriteLine("Oops! I'm older than 5 but not 6!");
}
Console.WriteLine("Thank God, I finally became older than 5.");
}
else // line 13
{
Console.WriteLine("Missed...When will I become 5 or close to 5?");
}
The else on line 7 is clearly related to if on line 3 while else on line 13 belongs to if on line 1. Finally, do note (C/C++ programmers especially) that if statements expect only Boolean expressions and not integer values. It's an error to write:
int flag = 0; if(flag = 1)
{
// do something...
}
Instead, you can either use:
int flag = 0;
if(flag == 1) |
// note == |
41
Programmers Heaven: C# School
{
// do something...
}
or,
bool flag |
= false; |
|
if(flag = |
true) |
// Boolean expression |
{ |
|
|
// do something...
}
The keys to avoiding confusion in the use of any complex combination of if...else are:
•Habit of using {} brackets with every if and else.
•Indentation: aligning the code to enhance readability. If you are using Visual Studio.Net or some other editor that supports coding, the editor will do indentation for you. Otherwise, you have to take care of this yourself.
I strongly recommend you follow the above two guidelines.
The switch...case statement
If you need to perform a series of specific checks, switch...case is present in C# just for this. The general structure of the switch...case statement is:
switch(integral or string expression)
{
case constant-expression: statements
breaking or jump statement // some other case blocks
...
default: statements
breaking or jump statement
}
It takes less time to use switch...case than using several if...else if statements. Let's look at it with an example:
using System;
42
Programmers Heaven: C# School
//To execute the program write "SwitchCaseExample 2" or
//any other number at command line,
//if the name of .exe file is "SwitchCaseExample.exe" namespace CSharpSchool
{
class SwitchCaseExample
{
//Demonstrates the use of switch...case statement along with
//the use of command line argument
static void Main(string [] userInput)
{
int input = int.Parse(userInput[0]);
//convert the string input to integer.
//Will throw a run-time exception if there is no input at run-time or if
//the input is not castable to integer.
switch(input) |
// what is input? |
{ |
|
case 1: |
// if it is 1 |
Console.WriteLine("You typed 1 (one) as the first command line argument"); |
|
break; |
// get out of switch block |
case 2: |
// if it is 2 |
Console.WriteLine("You typed 2 (two) as the first command line argument"); |
|
break; |
// get out of switch block |
case 3: |
// if it is 3 |
Console.WriteLine("You typed 3 (three) as the first command line argument"); |
|
break; |
// get out of switch block |
default: |
// if it is not any of the above |
Console.WriteLine("You typed a number other than 1, 2 and 3"); |
|
break; |
// get out of switch block |
} |
|
}
}
}
The program must be supplied with an integer command line argument. First, compile the program (at the command line or in Visual Studio.Net). Suppose we made an exe with name "SwitchCaseExample.exe", we would run it at the command line like this:
C:>SwitchCaseExample 2
You typed 2 (two) as command line argument
Or:
43
Programmers Heaven: C# School
C:>SwitchCaseExample 34
You typed a number other than 1, 2 and 3
If you did not enter any command line arguments or gave a non-integer argument, the program will raise an exception:
C:>SwitchCaseExample
Unhandled Exception: System.IndexOutOfRangeException:
Index was outside the bounds of the array.
at CSharpSchool.SwicthCaseExample.Main(String[] userInput) in
c:\visual studio projects\SwitchCaseExample\
SwitchCaseExample.cs :line 9
Let's get to internal working. First, we converted the first command line argument (userInput[0]) into an int variable input. For conversion, we used the static Parse() method of the int data type. This method takes a string and returns the equivalent integer or raises an exception if it can't. Next we checked the value of input variable using a switch statement:
switch(input)
{
...
}
Later, on the basis of the value of input, we took specific actions under respective case statements. Once our case specific statements end, we mark it with the break statement before the start of another case (or the default) block.
case 3: |
// |
if it is 3 |
|
|
Console.WriteLine("You typed 3 |
(three) as first command line argument"); |
|||
break; |
// |
get out of |
switch |
block |
|
|
|
|
|
If all the specific checks fail (input is none of 1,2 and 3), the statements under default executes.
default:
// if it is not any of the above
Console.WriteLine ("You typed a number other than 1, 2 and 3");
break; // get out of switch block
There are some important points to remember when using the switch...case statement in C#:
•You can use either integers (enumeration) or strings in a switch statement
•The expression following case must be constant. It is illegal to use a variable after case:
44
