Uploaded by dayan.libay

Applications-Devt-and-Emerging-Tech-C-1

advertisement
Z`
APPLICATIONS
DEVELOPMENT AND
EMERGING TECHNOLOGIES
Compiled by:
Elias A. Austria
Aleta C. Fabregas
1
Applications Development and Emerging Technologies
INSTRUCTIONAL MATERIAL
General Overview
The instructional materials Basic Topics of C# that will include control flow, iteration, methods,
objects and classes, graphical user Interface, exception handling and files and streams.
Advanced Topics of C# include assertions, collection classes, searching and sorting, regular
expressions, threads, networking with sockets, and C# database connectivity. By completing this
course, the student will be well equipped to work on small-scale industrial software projects. This
course concludes with a presentation of the final case project which uses the full power of the
language. It gives the better view developing application using C# program. It will provide
guidelines and standards on how an application will be developed, tested, implemented and
maintained.
General Objectives
After completion of this Instructional Material student should be able to:
1. Understand the basic and advanced topics of C# programming
2. Appreciate the Object-Oriented approach in C# Programming
3. Know the guidelines and standards of Developing Application Program
4. Develop an application program using C# Programming language
5. Learn the basic ways of planning, designing, developing, testing, implementing and
maintaining the application program
“Everybody in this country should learn how to program a computer… because it
teaches you how to think” – Steve Jobs
General Course Materials
Watch:
You can watch these YouTube link for more information about C# Programming Language
https://www.youtube.com/watch?v=GhQdlIFylQ8
https://www.youtube.com/watch?v=wLg-XdAmrak
Read:
For your course guide, read the syllabus Application Development and Emerging Technology
and the Instructional Materials.
Activities/ Assessments:
Make sure that you read and understand each module to answer the assessment activity at the
end of each module.
2
Table of Contents
Contents
Module 1....................................................................................................................................8
What is C#?.............................................................................................................................9
.Net Architecture ................................................................................................................. 11
C# IDEs ............................................................................................................................... 12
Module 2.................................................................................................................................. 14
Program Structure .............................................................................................................. 15
Types and Variables........................................................................................................... 16
C# Variables ......................................................................................................................... 20
Constants .............................................................................................................................. 20
Predefined Data Types in C# ................................................................................................. 21
C# Operators....................................................................................................................... 22
Arithmetic Operators ......................................................................................................... 22
Relational Operators .......................................................................................................... 23
Logical Operators .............................................................................................................. 24
Bitwise Operators .............................................................................................................. 25
Assignment Operators ....................................................................................................... 26
Miscellaneous Operators ................................................................................................... 27
Operator Precedence in C# ................................................................................................ 28
Basic Input/Output in C# .................................................................................................... 30
Console Input .................................................................................................................... 30
Console Output.................................................................................................................. 30
Control Flow ........................................................................................................................ 33
Conditional Statement ....................................................................................................... 33
Iteration Statement ............................................................................................................ 38
Arrays................................................................................................................................... 42
Single-Dimensional Arrays................................................................................................ 42
Multidimensional Arrays ................................................................................................... 43
Jagged Arrays .................................................................................................................... 45
Module 3................................................................................................................................... 49
Object-Oriented Programming .......................................................................................... 50
Classes and Objects .......................................................................................................... 50
3
Multiple Class Declaration ................................................................................................. 55
Partial classes ..................................................................................................................... 56
Static classes ...................................................................................................................... 58
Creating and Accessing Class Component Library......................................................... 58
Constructor and Destructor ............................................................................................... 61
Static Constructor ............................................................................................................... 62
Destructors .......................................................................................................................... 63
Method Overloading ........................................................................................................... 64
Method Overriding .............................................................................................................. 65
Encapsulation ..................................................................................................................... 71
Why do we need Encapsulation ......................................................................................... 72
Encapsulation Using Accessors and Mutators .................................................................... 73
Encapsulation Using Properties ......................................................................................... 73
Read Only Property ........................................................................................................... 74
Write Only Property .......................................................................................................... 75
Inheritance........................................................................................................................... 75
Constructor in Inheritance .............................................................................................. 78
Virtual Methods ............................................................................................................... 79
Hiding Methods ............................................................................................................... 80
Abstraction .......................................................................................................................... 81
Abstract Classes ............................................................................................................. 82
Sealed Classes ............................................................................................................... 83
Interface ............................................................................................................................ 84
Polymorphism ..................................................................................................................... 85
Types of Polymorphism..................................................................................................... 85
Static or Compile Time Polymorphism .............................................................................. 86
Dynamic / Runtime Polymorphism .................................................................................... 87
Preventing Derived class from overriding virtual members ................................................ 89
Accessing Base class virtual member................................................................................. 90
Module 4................................................................................................................................... 96
What is WPF? ..................................................................................................................... 97
WPF Architecture.............................................................................................................. 97
Advantages ........................................................................................................................ 98
Features ............................................................................................................................. 98
4
Create a Simple Application .............................................................................................. 99
Change the name of MainWindow.xaml .......................................................................... 101
Add a TextBlock control ................................................................................................. 101
Customize the text in the text block ................................................................................. 102
Add radio buttons ............................................................................................................ 102
Add display text for each radio button ............................................................................. 104
Set a radio button to be checked by default ...................................................................... 104
Add the button control ..................................................................................................... 105
Add code to the display button ........................................................................................ 106
Debug and test the application ......................................................................................... 106
What is XAML? ................................................................................................................. 107
Basic XAML ................................................................................................................... 108
Events in XAML ............................................................................................................. 109
Basic Controls ................................................................................................................... 112
The TextBlock control ..................................................................................................... 112
The Label control ............................................................................................................ 114
The TextBox control........................................................................................................ 117
The Button control........................................................................................................... 121
The CheckBox control ..................................................................................................... 124
The RadioButton control ................................................................................................. 128
The PasswordBox control ................................................................................................ 131
Module 5................................................................................................................................. 134
What is ADO.Net? ............................................................................................................ 135
The DataSet Class ........................................................................................................... 135
The DataTable Class........................................................................................................ 138
The DataRow Class ......................................................................................................... 139
The DataAdapter Object .................................................................................................. 140
The DataReader Object ................................................................................................... 140
DbCommand and DbConnection Objects ........................................................................ 140
ADO.Net on C# ................................................................................................................. 141
Connecting to a database ................................................................................................. 141
Connection pools ............................................................................................................. 141
Why use "using" in code.................................................................................................. 142
Executing the Commands ................................................................................................ 143
5
Parameterizing the data ................................................................................................... 143
Reading the data returned ................................................................................................ 144
Adding data to the SQL Server ........................................................................................ 145
Catching the errors from SQL Server............................................................................... 145
Working example ............................................................................................................ 146
Exception Handling in C# ................................................................................................ 150
try..catch..finally.............................................................................................................. 150
Uncaught Exceptions ....................................................................................................... 151
Multiple Catch Blocks ..................................................................................................... 154
Catching all Exceptions ................................................................................................... 155
Throwing an Exception ................................................................................................... 156
Re-throwing an Exception ............................................................................................... 156
Standard Exceptions ........................................................................................................ 157
User-defined Exceptions .................................................................................................. 158
Design Guidelines ........................................................................................................... 158
Module 6................................................................................................................................. 160
What is an Application? .................................................................................................. 161
What Is Application Development? ................................................................................. 161
Identifying the Issues ....................................................................................................... 161
Various Software Testing Concepts ............................................................................... 163
Difference Between Test Plan And Test Strategy............................................................. 163
Test Plan........................................................................................................................ 163
Test Plan Document ........................................................................................................ 163
Contents of Test plan Document (IEEE-829 test plan structure)....................................... 164
Test Strategy ................................................................................................................. 164
Test Strategy Document .............................................................................................. 164
Test Plan Vs Test Strategy .......................................................................................... 169
Difference Between Test Case And Test Script................................................................ 170
Difference Between Test Scenario and Test Condition .................................................... 171
Difference Between Test Procedure and Test Suite .......................................................... 173
Unit Testing ....................................................................................................................... 174
What do you mean by a Unit test ? .................................................................................. 174
Why do we need Unit test? .............................................................................................. 175
Let us start the show – create your first Unit test (step by Step) ....................................... 175
6
MS Unit tests................................................................................................................... 176
Test class requirements .................................................................................................... 179
Test method requirements................................................................................................ 180
Writing first Unit Test method ......................................................................................... 180
Analyze your test results why it failed ............................................................................. 182
Correct the bug to make test pass ..................................................................................... 182
Rerun Test to check if it is working or not ....................................................................... 182
TDD(Test Driven Development) Implementation using Unit Testing in C# ..................... 183
Let’s Implement TDD using MS Unit Testing ................................................................. 184
7
Module 1
Overview:
The module provides the fundamentals concepts of Java language as programming
language and software based platform. It discusses the characteristics, history, components
and the java editions
Module Objectives:
After successful completion of this module, you should be able to:
• Discuss the fundamental concepts of C# programming language.
• Know the history of C# programming language.
• Understand the different features released with C# versions.
8
What is C#?
C# is a strongly typed object-oriented programming language. C# is open source,
simple, modern, flexible, and versatile. In this article, let’s learn what C# is, what C# can
do, and how C# is different than C++ and other programming languages.
A programming language on computer science is a language that is used to write
software programs.
C# is a programming language developed and launched by Microsoft in 2001. C# is a
simple, modern, and object-oriented language that provides modern day developers
flexibility and features to build software that will not only work today but will be
applicable for years in the future.
Key characteristics of C# language include:
1.
2.
3.
4.
5.
6.
Modern and easy
Fast and open source
Cross platform
Safe
Versatile
Evolving
C# is modern and easy
C# is a simple, modern, and an object-oriented programming language. The purpose of
C# was to develop a programming language that is not only easy to learn but also
supports modern day functionality for all kind of software development.
If you look at the history of programming languages and their features, each
programming language was designed for a specific purpose to solve a specific need at
that time.
C# language however was designed to keep business and enterprises needs in mind.
C# language was designed for businesses to build all kinds of software by using one
single programming language.
C# provides functionality to support modern day software development. C# supports
Web, Mobile, and app development needs. Some of the modern-day programming
language features C# supports are generics, var types, auto initialization of types and
collections, lambda expressions, dynamic programming, asynchronous programming,
tuples, pattern matching, advanced debugging and exception handling, and more.
C# language syntaxes are influenced from C++, Java, Pascal and few other languages
that are easy to adopt. C# also avoids complexity and unstructured language features.
C# is fast and open source
C# is open source under the .NET Foundation, which is governed and run
independently of Microsoft. C# language specifications, compilers, and related tools are
open source projects on Github. While C# language feature design is lead by Microsoft,
the open source community is very active in the language development and
improvements.
9
C# is fast compare to several other high-level programming languages. C# 8 has many
performance improvements.
C# is cross platform
C# is cross platform programming language. You can build .NET applications that can
be deployed on Windows, Linux, and Mac platforms. C# apps can also be deployed in
cloud and containers.
C# is safe and efficient
C# is a type safe language. C# does not allow type conversions that may lead to data
loss or other problems. C# allows developers to write safe code. C# also focuses on
writing efficient code.
Here is a list of some of the key concepts in C# that helps write safe and efficient code.
•
•
•
•
•
•
•
Unsafe type casting is not allowed.
Nullable and non-nullable types are supported in C#.
Declare a readonly struct to express that a type is immutable and enables the
compiler to save copies when using in parameters.
Use a ref readonly return when the return value is a struct larger than IntPtr.Size
and the storage lifetime is greater than the method returning the value.
When the size of a readonly struct is bigger than IntPtr.Size, you should pass it
as an in parameter for performance reasons.
Never pass a struct as an in parameter unless it's declared with the readonly
modifier because it may negatively affect performance and could lead to an
obscure behavior.
Use a ref struct, or a readonly ref struct such as Span<T> or ReadOnlySpan<T>
to work with memory as a sequence of bytes.
C# is versatile
C# is a Swiss army knife. While most programming languages were designed for a
specific purpose, C# was designed to do C#. We can use C# to build today’s modern
software applications. C# can be used to develop all kind of applications including
Windows client apps, components and libraries, services and APIs, Web applications,
Mobile apps, cloud applications, and video games.
Here is a list of types of applications C# can build,
•
•
•
•
•
•
•
•
•
•
•
Windows client applications
Windows libraries and components
Windows services
Web applications
Web services and Web API
Native iOS and Android mobile apps
Backend services
Azure cloud applications and services
Backend database using ML/Data tools
Interoperability software such as Office, SharePoint, SQL Server and so on.
Artificial Intelligence and Machine learning
10
•
•
•
•
Blockchains and distributed ledger technology including cryptocurrency
Internet of Things (IoT) devices
Gaming consoles and gaming systems
Video games
C# is evolving
C# 8.0 is the latest version of C#. If you look at C# language history, C# is evolving
faster than any other languages. Thanks to Microsoft and a strong community support.
C# was initially designed to write Windows client applications but today, C# can do
pretty much anything from console apps, cloud app, and modern machine learning
software.
.Net Architecture
C# programs run on .NET, a virtual execution system called the common language
runtime (CLR) and a set of class libraries. The CLR is the implementation by Microsoft
of the common language infrastructure (CLI), an international standard. The CLI is the
basis for creating execution and development environments in which languages and
libraries work together seamlessly.
Source code written in C# is compiled into an intermediate language (IL) that conforms to the
CLI specification. The IL code and resources, such as bitmaps and strings, are stored in an
assembly, typically with an extension of .dll. An assembly contains a manifest that provides
information about the assembly's types, version, and culture.
When the C# program is executed, the assembly is loaded into the CLR. The CLR performs
Just-In-Time (JIT) compilation to convert the IL code to native machine instructions. The CLR
provides other services related to automatic garbage collection, exception handling, and
resource management. Code that's executed by the CLR is sometimes referred to as "managed
code," in contrast to "unmanaged code," which is compiled into native machine language that
targets a specific platform.
Language interoperability is a key feature of .NET. IL code produced by the C# compiler
conforms to the Common Type Specification (CTS). IL code generated from C# can interact
with code that was generated from the .NET versions of F#, Visual Basic, C++, or any of more
than 20 other CTS-compliant languages. A single assembly may contain multiple modules
written in different .NET languages, and the types can reference each other as if they were
written in the same language.
In addition to the run time services, .NET also includes extensive libraries. These libraries
support many different workloads. They're organized into namespaces that provide a wide
variety of useful functionality for everything from file input and output to string manipulation to
XML parsing, to web application frameworks to Windows Forms controls. The typical C#
application uses the .NET class library extensively to handle common "plumbing" chores.
11
The following table summarizes the C# versions with year and features.
Version Year Features
1999- Modern, Object Oriented, Simple, Flexible, Typesafe, Managed,
1.0
2002 Garbage Collection, Cross-platform
2.0
2005 Generics, Anonymous Method, Partial Class, Nullable Type
3.0
2008 LINQ, Lamda Expression, Extension Method, Anonymous Type, Var
4.0
2010 Named and Optional Parameters, Dynamic Binding
5.0
2012 Async Programming
Compiler-as-a-service (Roslyn), Exception filters, Await in catch/finally
blocks, Auto property initializers, Dictionary initializer, Default values for
6.0
2015
getter-only properties, Expression-bodied members. Null propagator,
String interpolation, nameof operator
Tuples, Out variables, Pattern matching, Deconstruction, Local
functions, Digit separators, Binary literals, Ref returns and locals,
7.0
2017 Generalized async return types, Expression bodied constructors and
finalizers, Expression bodied getters and setters, Throw can also be
used as expression
7.1
2017 Async main, Default literal expressions, Inferred tuple element names
Reference semantics with value types, Non-trailing named arguments,
7.2
2017 Leading underscores in numeric literals, private protected access
modifier
Accessing fixed fields without pinning, Reassigning ref local variables,
7.3
2018 Using initializers on stackalloc arrays, Using fixed statements with any
type that supports a pattern, Using additional generic constraints
Nullable reference types, Async streams, ranges and indices, default
8.0
2019 implementation of interface members, recursive patterns, switch
expressions, target-type new expressions
C# IDEs
The easiest way to get started with C#, is to use an IDE. An IDE (Integrated Development
Environment) is used to edit and compile code. Mostly, we use Visual Studio in coding
applications that will be written in C#. C# applications uses .NET Framework, so it makes sense
to use Visual Studio, as the program, the framework, and the language, are all created by
Microsoft.
12
Course Materials:
https://www.c-sharpcorner.com/article/what-is-c-sharp/
https://www.w3schools.com/cs/cs_getstarted.asp
https://docs.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/
Activities/Assessments:
1. Make a research about the latest updates in C# on application development.
2. Determine the advantages of C# program as an application development program.
13
Module 2
Overview:
This module gives the detailed description of the fundamental statements of C#, from
data types, variables, constants, operators, input/output statements, conditional, looping, arrays
and further manipulation of arrays. This module explains the simplicity of the C# program and
uniqueness that is used as application development program nowadays.
Module Objectives:
After successful Completion of this module, you should be able to:
• Know the parts of the C# program.
• Learn and understand the basic structures and basic statements of the C# program.
• Apply the learned C# statements to develop a simple application.
14
Program Structure
The key organizational concepts in C# are programs, namespaces, types, members,
and assemblies. Programs declare types, which contain members and can be organized
into namespaces. Classes, structs, and interfaces are examples of types. Fields,
methods, properties, and events are examples of members. When C# programs are
compiled, they're physically packaged into assemblies. Assemblies typically have the file
extension .exe or .dll, depending on whether they implement applications or libraries,
respectively.
As a small example, consider an assembly that contains the following code:
The fully qualified name of this class is Acme.Collections.Stack. The class contains several
members: a field named top, two methods named Push and Pop, and a nested class
named Entry. The Entry class further contains three members: a field named next, a field
named data, and a constructor. The Stack is a generic class. It has one type
parameter, T that is replaced with a concrete type when it's used.
15
Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and
symbolic information in the form of metadata. Before it's executed, the Just-In-Time (JIT) compiler
of .NET Common Language Runtime converts the IL code in an assembly to processor-specific
code.
Because an assembly is a self-describing unit of functionality containing both code and metadata,
there's no need for #include directives and header files in C#. The public types and members
contained in a particular assembly are made available in a C# program simply by referencing that
assembly when compiling the program.
For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:
To compile this program, you would need to reference the assembly containing the stack class
defined in the earlier example.
C# programs can be stored in several source files. When a C# program is compiled, all of the
source files are processed together, and the source files can freely reference each other.
Conceptually, it's as if all the source files were concatenated into one large file before being
processed. Forward declarations are never needed in C# because, with few exceptions,
declaration order is insignificant. C# doesn't limit a source file to declaring only one public type
nor does it require the name of the source file to match a type declared in the source file.
Types and Variables
There are two kinds of types in C#: value types and reference types. Variables of value
types directly contain their data. Variables of reference types store references to their
data, the latter being known as objects. With reference types, it's possible for two
variables to reference the same object and 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 isn't possible for operations on one to affect the
other (except for ref and out parameter variables).
16
An identifier is a variable name. An identifier is a sequence of unicode characters without
any whitespace. An identifier may be a C# reserved word, if it's prefixed by @. Using a
reserved word as an identifier can be useful when interacting with other languages.
C#'s value types are further divided into simple types, enum types, struct types, nullable
value types, and tuple value types. C#'s reference types are further divided into class
types, interface types, array types, and delegate types.
The following outline provides an overview of C#'s type system.
•
Value types
o Simple types
▪ Signed integral: sbyte, short, int, long
▪ Unsigned integral: byte, ushort, uint, ulong
▪ Unicode characters: char, which represents a UTF-16
code unit
▪ IEEE binary floating-point: float, double
▪ High-precision decimal floating-point: decimal
▪ Boolean: bool, which represents Boolean values—values
that are either true or false
o Enum types
▪ User-defined types of the form enum E {...}. An enum type is
a distinct type with named constants. Every enum type has
an underlying type, which must be one of the eight
integral types. The set of values of an enum type is the
same as the set of values of the underlying type.
o Struct types
17
▪
•
User-defined types of the form struct S {...}
o Nullable value types
▪ Extensions of all other value types with a null value
o Tuple value types
▪ User-defined types of the form (T1, T2, ...)
Reference types
o Class types
▪ Ultimate base class of all other types: object
▪ Unicode strings: string, which represents a sequence of
UTF-16 code units
▪ User-defined types of the form class C {...}
o Interface types
▪ User-defined types of the form interface I {...}
o Array types
▪ Single-dimensional, multi-dimensional, and jagged. For
example: int[], int[,], and int[][]
o Delegate types
▪ User-defined types of the form delegate int D(...)
C# programs use type declarations to create new types. A type declaration specifies the
name and the members of the new type. Six of C#'s categories of types are userdefinable: class types, struct types, interface types, enum types, delegate types, and tuple
value types.
•
•
•
•
A class type defines a data structure that contains data members (fields) and
function members (methods, properties, and others). Class types support
single inheritance and polymorphism, mechanisms whereby derived classes
can extend and specialize base classes.
A struct type is similar to a class type in that it represents a structure with data
members and function members. However, unlike classes, structs are value
types and don't typically require heap allocation. Struct types don't support
user-specified inheritance, and all struct types implicitly inherit from
type object.
An interface type defines a contract as a named set of public members.
A class or struct that implements an interface must provide implementations of
the interface's members. An interface may inherit from multiple base
interfaces, and a class or struct may implement multiple interfaces.
A delegate type represents references to methods with a particular parameter
list and return type. Delegates make it possible to treat methods as entities
that can be assigned to variables and passed as parameters. Delegates are
analogous to function types provided by functional languages. They're also
similar to the concept of function pointers found in some other languages.
Unlike function pointers, delegates are object-oriented and type-safe.
The class, struct, interface, and delegate types all support generics, whereby they can be
parameterized with other types.
18
C# supports single-dimensional and multi-dimensional arrays of any type. Unlike the
types listed above, array types don't have to be declared before they can be used.
Instead, array types are constructed by following a type name with square brackets. For
example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int,
and int[][] is a single-dimensional array of single-dimensional arrays, or a "jagged" array,
of int.
Nullable types don't require a separate definition. For each non-nullable type T, there's a
corresponding nullable type T?, which can hold an additional value, null. For
instance, int? is a type that can hold any 32-bit integer or the value null, and string? is a type
that can hold any string or the value null.
C#'s type system is unified such that a value of any type can be treated as an object. Every
type in C# directly or indirectly derives from the object class type, and object is the ultimate
base class of all types. Values of reference types are treated as objects simply by viewing
the values as type object. Values of value types are treated as objects by
performing boxing and unboxing operations. In the following example, an int value is
converted to object and back again to int.
When a value of a value type is assigned to an object reference, a "box" is allocated to
hold the value. That box is an instance of a reference type, and the value is copied into
that box. Conversely, when an object reference is cast to a value type, a check is made
that the referenced object is a box of the correct value type. If the check succeeds, the
value in the box is copied to the value type.
C#'s unified type system effectively means that value types are treated
as object references "on demand." Because of the unification, general-purpose libraries
that use type object can be used with all types that derive from object, including both
reference types and value types.
There are several kinds of variables in C#, including fields, array elements, local
variables, and parameters. Variables represent storage locations. Every variable has a
type that determines what values can be stored in the variable, as shown below.
•
•
•
Non-nullable value type
o A value of that exact type
Nullable value type
o A null value or a value of that exact type
object
o A null reference, a reference to an object of any reference type, or
a reference to a boxed value of any value type
19
•
•
•
•
Class type
o A null reference, a reference to an instance of that class type, or a
reference to an instance of a class derived from that class type
Interface type
o A null reference, a reference to an instance of a class type that
implements that interface type, or a reference to a boxed value of
a value type that implements that interface type
Array type
o A null reference, a reference to an instance of that array type, or a
reference to an instance of a compatible array type
Delegate type
o A null reference or a reference to an instance of a compatible
delegate type
C# Variables
Variables are containers for storing data values.
In C#, there are different types of variables (defined with different keywords), for
example:
•
•
•
•
•
int - stores integers (whole numbers), without decimals, such as 123 or -123
double - stores floating point numbers, with decimals, such as 19.99 or -19.99
char - stores single characters, such as 'a' or 'B'. Char values are surrounded by
single quotes
string - stores text, such as "Hello World". String values are surrounded by double
quotes
bool - stores values with two states: true or false
Syntax:
Example:
Constants
You can add the const keyword if you don't want others (or yourself) to overwrite existing
values (this will declare the variable as "constant", which means unchangeable and readonly).
20
Example:
Predefined Data Types in C#
C# includes some predefined value types and reference types. The following table
lists predefined data types:
Type
Description
Range
Suffix
byte
sbyte
short
ushort
int
8-bit unsigned integer
8-bit signed integer
16-bit signed integer
16-bit unsigned integer
32-bit signed integer
uint
long
32-bit unsigned integer
64-bit signed integer
ulong
64-bit unsigned integer
float
32-bit Single-precision floating point
type
64-bit double-precision floating point
type
128-bit decimal type for financial and
monetary calculations
double
decimal
char
16-bit single Unicode character
bool
object
string
8-bit logical true/false value
Base type of all other types.
A sequence of Unicode characters
21
0 to 255
-128 to 127
-32,768 to 32,767
0 to 65,535
-2,147,483,648
to
2,147,483,647
0 to 4,294,967,295
u
-9,223,372,036,854,775,808 l
to
9,223,372,036,854,775,807
0 to
ul
18,446,744,073,709,551,615
-3.402823e38 to
f
3.402823e38
-1.79769313486232e308 to d
1.79769313486232e308
(+ or -)1.0 x 10e-28
m
to
7.9 x 10e28
Any valid character, e.g. a,*,
\x0058 (hex), or\u0058
(Unicode)
True or False
DateTime Represents date and time
0:00:00am 1/1/01
to
11:59:59pm 12/31/9999
C# Operators
An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. C# has rich set of built-in operators and provides the following type of operators
•
Arithmetic Operators
Relational Operators
Logical Operators
Bitwise Operators
Assignment Operators
Misc Operators
•
•
•
•
•
This tutorial explains the arithmetic, relational, logical, bitwise, assignment, and other operators
one by one.
Arithmetic Operators
Following table shows all the arithmetic operators supported by C#. Assume variable A holds 10
and variable B holds 20 then −
Operator
+
Description
Adds two operands
Example
A + B = 30
22
-
Subtracts second operand from the first
A - B = -10
*
Multiplies both operands
A * B = 200
/
Divides numerator by de-numerator
B/A=2
%
Modulus Operator and remainder of after an integer
division
B%A=0
++
Increment operator increases integer value by one
A++ = 11
--
Decrement operator decreases integer value by one
A-- = 9
Relational Operators
Following table shows all the relational operators supported by C#. Assume variable A holds 10
and variable B holds 20, then −
Operator
Description
Example
==
Checks if the values of two operands are equal or not,
if yes then condition becomes true.
(A == B) is not
true.
!=
Checks if the values of two operands are equal or not,
if values are not equal then condition becomes true.
(A != B) is true.
>
Checks if the value of left operand is greater than the
value of right operand, if yes then condition becomes
true.
(A > B) is not
true.
23
<
Checks if the value of left operand is less than the
value of right operand, if yes then condition becomes
true.
(A < B) is true.
>=
Checks if the value of left operand is greater than or
equal to the value of right operand, if yes then
condition becomes true.
(A >= B) is not
true.
<=
Checks if the value of left operand is less than or
equal to the value of right operand, if yes then
condition becomes true.
(A <= B) is true.
Logical Operators
Following table shows all the logical operators supported by C#. Assume variable A holds
Boolean value true and variable B holds Boolean value false, then −
Operator
Description
Example
&&
Called Logical AND operator. If both the operands
are non zero then condition becomes true.
(A && B) is false.
||
Called Logical OR Operator. If any of the two
operands is non zero then condition becomes true.
(A || B) is true.
!
Called Logical NOT Operator. Use to reverses the
logical state of its operand. If a condition is true then
Logical NOT operator will make false.
!(A && B) is true.
24
Bitwise Operators
Bitwise operator works on bits and perform bit by bit operation. The truth tables for &, |, and ^
are as follows −
p
q
p&q
p|q
p^q
0
0
0
0
0
0
1
0
1
1
1
1
1
1
0
1
0
0
1
1
Assume if A = 60; and B = 13; then in the binary format they are as follows −
A = 0011 1100
B = 0000 1101
------------------A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
The Bitwise operators supported by C# are listed in the following table. Assume variable A holds
60 and variable B holds 13, then −
Operator
&
Description
Binary AND Operator copies a bit to the result
if it exists in both operands.
25
Example
(A & B) = 12, which is 0000
1100
|
Binary OR Operator copies a bit if it exists in
either operand.
(A | B) = 61, which is 0011
1101
^
Binary XOR Operator copies the bit if it is set in
one operand but not both.
(A ^ B) = 49, which is 0011
0001
Binary Ones Complement Operator is unary
and has the effect of 'flipping' bits.
(~A ) = -61, which is 1100
0011 in 2's complement due to
a signed binary number.
<<
Binary Left Shift Operator. The left operands
value is moved left by the number of bits
specified by the right operand.
A << 2 = 240, which is 1111
0000
>>
Binary Right Shift Operator. The left operands
value is moved right by the number of bits
specified by the right operand.
A >> 2 = 15, which is 0000
1111
~
Assignment Operators
There are following assignment operators supported by C# −
Operator
Description
Example
=
Simple assignment operator, Assigns values from right
side operands to left side operand
C = A + B assigns
value of A + B into
C
+=
Add AND assignment operator, It adds right operand to
the left operand and assign the result to left operand
C += A is
equivalent to C =
C+A
-=
Subtract AND assignment operator, It subtracts right
operand from the left operand and assign the result to left
operand
C -= A is
equivalent to C =
C-A
26
*=
Multiply AND assignment operator, It multiplies right
operand with the left operand and assign the result to left
operand
C *= A is
equivalent to C =
C*A
/=
Divide AND assignment operator, It divides left operand
with the right operand and assign the result to left
operand
C /= A is
equivalent to C =
C/A
%=
Modulus AND assignment operator, It takes modulus
using two operands and assign the result to left operand
C %= A is
equivalent to C =
C%A
<<=
Left shift AND assignment operator
C <<= 2 is same
as C = C << 2
>>=
Right shift AND assignment operator
C >>= 2 is same
as C = C >> 2
&=
Bitwise AND assignment operator
C &= 2 is same as
C=C&2
^=
bitwise exclusive OR and assignment operator
C ^= 2 is same as
C=C^2
|=
bitwise inclusive OR and assignment operator
C |= 2 is same as
C=C|2
Miscellaneous Operators
There are few other important operators including sizeof, typeof and ? : supported by C#.
Operator
Description
Example
27
sizeof()
Returns the size of a data type.
sizeof(int), returns 4.
typeof()
Returns the type of a class.
typeof(StreamReader);
Returns the address of an variable.
&a; returns actual address of the
variable.
Pointer to a variable.
*a; creates pointer named 'a' to a
variable.
Conditional Expression
If Condition is true ? Then value X :
Otherwise value Y
Determines whether an object is of a
certain type.
If( Ford is Car) // checks if Ford is an
object of the Car class.
&
*
?:
is
as
Object obj = new
StringReader("Hello");
Cast without raising an exception if the
cast fails.
StringReader r = obj as StringReader;
Operator Precedence in C#
Operator precedence determines the grouping of terms in an expression. This affects evaluation
of an expression. Certain operators have higher precedence than others; for example, the
multiplication operator has higher precedence than the addition operator.
For example x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher
precedence than +, so the first evaluation takes place for 3*2 and then 7 is added into it.
Here, operators with the highest precedence appear at the top of the table, those with the lowest
appear at the bottom. Within an expression, higher precedence operators are evaluated first.
28
Category
Operator
Associativity
Postfix
() [] -> . ++ - -
Left to right
Unary
+ - ! ~ ++ - - (type)* & sizeof
Right to left
Multiplicative
*/%
Left to right
Additive
+-
Left to right
Shift
<< >>
Left to right
Relational
< <= > >=
Left to right
Equality
== !=
Left to right
Bitwise AND
&
Left to right
Bitwise XOR
^
Left to right
Bitwise OR
|
Left to right
Logical AND
&&
Left to right
Logical OR
||
Left to right
Conditional
?:
Right to left
Assignment
= += -= *= /= %=>>= <<= &= ^= |=
Right to left
29
Comma
,
Left to right
Basic Input/Output in C#
Console Input
The Console class allows using the Write () and the WriteLine () functions to display things on
the screen. While the Console.Write () method is used to display something on the screen, the
Console class provides the Read () method to get a value from the user. To use it, the name of
a variable can be assigned to it. The syntax used is:
variableName = Console. Read();
This simply means that, when the user types something and presses Enter, what the user had
typed would be given (the word is assigned) to the variable specified on the left side of the
assignment operator.
Read() doesn’t always have to assign its value to a variable. For example, it can be used on its
own line, which simply means that the user is expected to type something but the value typed
by the user would not be used for any significant purpose. For example some versions of C#
(even including Microsoft’s C# and Borland C#Builder) would display the DOS window briefly
and disappear. You can use the Read() function to wait for the user to press any key in order to
close the DOS window.
Besides Read(), the Console class also provides the ReadLine() method. Like the WriteLine()
member function, after performing its assignment, the ReadLine() method sends the caret to the
next line. Otherwise, it plays the same role as the Read() function.
string FirstName;
Console.write(“Enter First Name: “);
FirstName = console.ReadLine();
In C#, everything the user types is a string and the compiler would hardly analyze it without your
explicit asking it to do so. Therefore, if you want to get a number from the user, first request a
string. after getting the string, you must convert it to a number. To perform this conversion,
each data type of the .NET Framework provides a mechanism called Parse. To use Parse(), type
the data type, followed by a period, followed by Parse, and followed by parentheses. In the
parentheses of Parse, type the string that you requested from the user.
Console Output
30
Instead of using two Write() or a combination of Write() and WriteLine() to display data, you can
convert a value to a string and display it directly. To do this, you can provide two strings to the
Write() or WriteLine() and separate them with a comma:
1. The first part of the string provided to Write() or WriteLine() is the complete string that would
display to the user. This first string itself can be made of different sections:
(a) One section is a string in any way you want it to display
(b) Another section is a number included between an opening curly bracket “{“and a closing curly
bracket “}”.This combination of”{” and “}”is referred to as a, placeholder.
You can put the placeholder anywhere inside of the string. The first placeholder must have
number O. The second must have number 1, etc. With this technique, you can create the string
anyway you like and use the placeholders anywhere inside of the string
2. The second part of the string provided to Write() or WriteLine() is the value that you want to
display. It can be one value if you used only one placeholder with 0 in the first string. It’ you used
different placeholders, you can then provide a different value for each one of them in this second
part, separating the values with a comma
Here are examples:
As mentioned already, the numeric value typed in the curly brackets of the first part is an ordered
number. If you want to display more than one value, provide each incremental value in its curly
brackets. The syntax used is:
write(“To Display {0} {l} {2} {n}, First, second, Third, nth);
You can use the sections between a closing curly bracket and an opening curly bracket to create
a meaningful sentence.
31
The System names pace provides a specific letter that you can use in the Write() or WriteLine()’s
placeholder for each category of data to display. To format a value, in the placeholder of the
variable or value, after the number, type a colon and one of the appropriate letter from the
following table. If you are using ToStringO, then, in the parentheses of
ToString(), you can include a specific letter or combination inside of double-quotes. The letters
and their meanings are:
32
Control Flow
Control flow (or alternatively, flow of control) refers to the order in which the individual
statements, instructions or function calls of an imperative or a declarative program are
executed or evaluated.
Conditional Statement
A statement that can be executed based on a condition is known as a “Conditional Statement”.
If-Else Statement
The if statement is used to check for a condition and based on it decide whether or not to execute
a code block. The if code block is executed only if the condition is true otherwise further
instruction or else block gets executed. You can write nested if blocks if required. Following
diagram shows the basic flow of a default if-else statement. It is not mandatory to have
an else block after an if block. The else statement is used to specify the code which has to be
executed if the condition doesn't return true.
33
Let's see a practical implementation of if statement.
using System;
namespace Studytonight
{
public class Program
{
public static void Main(string[] args)
{
int i = 100;
if(i > 0)
{
Console.WriteLine("Given number is positive!");
}
else
{
Console.WriteLine("Given number is negative!");
}
Console.ReadKey();
}
}
}
Output:
Given number is positive!
Try running the above program by providing a negative value to i variable, the else code will get
executed.
34
If….Else If…..Else Statement
If we have to specify two conditions which are related to each other, we can use the else
if statement to specify the second condition and its related code block. We can use multiple else
if blocks to add multiple conditions but it requires atleast one if block at the beginning, we can't
directly write else and else if statements without having any if block.
using System;
namespace Studytonight
{
public class Program
{
public static void Main(string[] args)
{
int i = 0; // Zero is neutral in nature
if(i > 0)
{
Console.WriteLine("Given number is positive!");
}
else if(i < 0)
{
Console.WriteLine("Given number is negative!");
}
else
{
Console.WriteLine("Given number is neither positive nor negative!");
}
Console.ReadKey();
}
}
}
Output:
Given number is neither positive nor negative!
Switch Case Statement
The switch statement executes only one statement from multiple given statements associated
with conditions. If any condition returns true, then the code statements below it gets executed.
Following diagram shows the basic flow of a switch statement.
35
Let's see the practical implementation of the switch statement,
using System;
namespace Studytonight
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("1.Additon\n2.Subtraction\n3.Division\nEnter your choice:");
int c = Convert.ToInt32(Console.ReadLine());
switch(c)
{
case 1: Console.WriteLine("\nAddition selected!"); break;
case 2: Console.WriteLine("\nSubtraction selected!"); break;
case 3: Console.WriteLine("\nDivision selected!"); break;
default: Console.WriteLine("\nYour choice not found!"); break;
}
Console.ReadKey();
}
36
}
}
Output:
1.Additon
2.Subtraction
3.Division
Enter your choice: 4
Your choice not found!
As you can see in the above code example, if none of the case is matched, then default case will
be executed. If your choice is 1 then the only case 1 will be executed and other cases will not
execute not even the default case. The break statement is used to come out of any switch case,
if we remove the break statements from all the case blocks, then after the execution of the case
for which the condition is true, the default condition will also get executed.
Goto Statement
The goto statement is used to transfer the control from a loop or switch case to a specified label.
It is also known as a jump statement. It is generally recommended to avoid using it as it makes
the program more complex. In the following example, if the user is logged in then we have directly
jumped our code to success label.
using System;
namespace Studytonight
{
public class Program
{
public static void Main(string[] args)
{
string user = "login";
if(user=="login")
{
goto success;
}
success:
Console.WriteLine("Welcome to Studytonight!");
Console.ReadKey();
}
}
}
Output:
Welcome to Studytonight!
37
Iteration Statement
An Iteration is just a fancy word for a loop. An Iteration statement will perform operations a set
number of times until you tell it to stop, with a true or false value.
Iteration statements also depend on an expression being evaluated until a that expression
evaluates to false. This is called “loop termination criteria” and depends on Boolean values being
evaluated.
While statement
The while statement is frequently used in code due to it’s simplicity and speed. In the example
above I used a combination of do and while to create a do-while loop, but while can operate on
it’s own. Let’s do the count to 10 with just a while loop and see how it works:
static void Main()
{
int i = 0, limit = 10;
while (i < limit)
{
Console.WriteLine("Count: " + i);
i++;
}
}
This loop is pretty much as simple as it gets. The while simply runs while the expression
evaluates to true .
In plain English:
•
•
•
While our value (i) is less than another value (limit) execute,
Write out the value (i)
Increment the value (i)
This loop will repeat until the expression (i < limit) evaluates to false. If it is already set to false,
nothing in the while loop will execute. Type the following in and run it:
static void Main()
{
int i = 10, limit = 10;
while (i < limit)
{
Console.WriteLine("Count: " + i);
i++;
}
}
38
When you run this, you’ll notice nothing happens. This is because (i) is not less than (limit) so
the loop never runs. This is ideal for most situations, but you may want your loop to run at least
once, which brings us to the next loop.
Do statement (with while)
I used the do statement in the first example in combination with the while statment. Do executes
a statement or block of statements until a specified expression evaluates to FALSE. You can
use do without braces if it’s only a single statement:
do Console.WriteLine("Count: " + i); while (i < limit);
but if you need to execute more than one statement you’ll need to enclose them in braces:
do
{
Console.WriteLine("Count: " + i);
i++;
} while (i < limit);
The mechanics of this should be fairly obvious: in plain English we want to:
•
•
•
write a value (i) to the console
increment the value
repeat while that value is less than another (limit)
This is pretty simple, but take a note of the order of operations with this loop. The thing to
remember about a do-while loop such as the one above is this:
A do-while loop will always execute then evaluate an expression to see if it needs to continue
looping. The statement will always be executed at least once, while a while loop will only
execute if a condition is evaluated as true. This is an important distinction.
We can break out of a while loop early if needed:
int i = 0, limit = 10;
do
{
if (i == 7)
{
break;
}else
{
Console.WriteLine("Count: " + i);
}
i++;
}
39
while (i < limit);
When you run this you will see the following output:
Count: 0 Count: 1 Count: 2 Count: 3 Count: 4 Count: 5 Count: 6
This is because you put in a condition that evaluated whether i was 7 and if so, terminate the
loop. This can come in pretty handy. You can also use goto, return and flow to break out of this
loop as well. There are times where you may want to check for something in each iteration and
if it happens, break out of it to correct it or stop the process.
For Statement
The for loop is a little more tricky to understand at first, but it performs the same function as a
while loop. The for loop isn’t faster or any more powerful, but it is easier to construct and read
so it’s mostly a programmer advantage (very important).
Here’s an example of a for loop that counts to 10:
public static void Main ()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
When you compile and run this it should look pretty familiar to you. The output is the same, but
as you can see constructing the loop is easier and there is less code to look at. Let’s explain
how it works in plain English:
•
•
•
test to see if our initial value (i) is less than ten
if so, increment it and execute next expression
write out the value (i)
Foreach statement
The foreach statement is a little different than for in that it repeats a group of statements for
each element in an array, object or collection. It is used for reading those elements in the
sequence defined by the foreach statement.
40
Here is an example of our count to 10 app with a foreach statement:
public static void Main ()
{
int[] ourArray = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9 };
foreach (int i in ourArray)
{
System.Console.WriteLine(i);
}
}
As you can see in this example it’s a little different because we’re creating an array on line 3
that we iterate though. Since this is an integer array we create the int(i) to represent the element
of the array. Then we execute everything in the brackets each time a new element in the array
is found. While there are new elements in i we will display them, then as soon as there are no
more we exit from the loop.
But this doesn’t just work on integer arrays, it works on all types of arrays and objects where
you use an iterator. Here’s an example with strings:
public static void Main ()
{
string[] ourArray = new string[] { "C# Tutorials", "Python Tutorials",
"Underwater Basket Weaving" };
foreach (string s in ourArray)
{
System.Console.WriteLine(s);
}
}
Notice how the variable (s) is pulled from the array and displayed until there are no more in the
array. This is a great way to iterate through arrays, lists, collections and objects.
Note that you should generally only use this for read only operations. If you start messing with
items of an array as it’s being traversed you get some pretty unexpected results.
The foreach statement is great for working with data objects, and is extremely powerful and
easy to use.
41
Arrays
An array is a container object that holds a fixed number of values of a single type. Each
item in an array is called an element, and each element is accessed by its numerical
index. Array indices are always zero-based; the first element of the array is always
indexed with 0.
Obtaining an array is a two-step process.
•
•
First, you must declare a variable of the desired array type
Second, you must allocate the memory that will hold the array, using new, and
assign it to the array variable
So, let us see how can we declare arrays in different ways.
An array has the following properties:
•
•
•
•
•
•
•
An array can be single-dimensional, multidimensional or jagged.
The number of dimensions and the length of each dimension are established when
the array instance is created. These values can't be changed during the lifetime of
the instance.
The default values of numeric array elements are set to zero, and reference
elements are set to null.
A jagged array is an array of arrays, and therefore its elements are reference types
and are initialized to null.
Arrays are zero indexed: an array with n elements is indexed from 0 to n-1.
Array elements can be of any type, including an array type.
Array types are reference types derived from the abstract base type Array. Since
this type implements IEnumerable and IEnumerable<T>, you can
use foreach iteration on all arrays in C#.
Single-Dimensional Arrays
You create a single-dimensional array using the new operator specifying the array element type
and the number of elements. The following example declares an array of five integers:
int[] array = new int[5];
This array contains the elements from array[0] to array[4]. The elements of the array are initialized
to the default value of the element type, 0 for integers.
42
Arrays can store any element type you specify, such as the following example that declares an
array of strings:
string[] stringArray = new string[6];
Array Initialization
You can initialize the elements of an array when you declare the array. The length specifier isn't
needed because it's inferred by the number of elements in the initialization list. For example:
int[] array1 = new int[] { 1, 3, 5, 7, 9 };
The following code shows a declaration of a string array where each array element is initialized
by a name of a day:
string[] weekDays = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
You can avoid the new expression and the array type when you initialize an array upon
declaration, as shown in the following code. This is called an implicitly typed array:
int[] array2 = { 1, 3, 5, 7, 9 };
string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
You can declare an array variable without creating it, but you must use the new operator when
you assign a new array to this variable. For example:
int[] array3;
array3 = new int[] { 1, 3, 5, 7, 9 }; // OK
//array3 = {1, 3, 5, 7, 9}; // Error
Multidimensional Arrays
Arrays can have more than one dimension. For example, the following declaration creates a twodimensional array of four rows and two columns.
int[,] array = new int[4, 2];
The following declaration creates an array of three dimensions, 4, 2, and 3.
int[,,] array1 = new int[4, 2, 3];
43
Array Initialization
You can initialize the array upon declaration, as is shown in the following example.
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
// Three-dimensional array.
int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[,,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// Accessing array elements.
System.Console.WriteLine(array2D[0, 0]);
System.Console.WriteLine(array2D[0, 1]);
System.Console.WriteLine(array2D[1, 0]);
System.Console.WriteLine(array2D[1, 1]);
System.Console.WriteLine(array2D[3, 0]);
System.Console.WriteLine(array2Db[1, 0]);
System.Console.WriteLine(array3Da[1, 0, 1]);
System.Console.WriteLine(array3D[1, 1, 2]);
// Getting the total count of elements or the length of a given dimension.
var allLength = array3D.Length;
var total = 1;
for (int i = 0; i < array3D.Rank; i++)
{
total *= array3D.GetLength(i);
}
System.Console.WriteLine("{0} equals {1}", allLength, total);
You can also initialize the array without specifying the rank.
int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
If you choose to declare an array variable without initialization, you must use the new operator to
assign an array to the variable. The use of new is shown in the following example.
44
int[,] array5;
array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // OK
//array5 = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error
The following example assigns a value to a particular array element.
array5[2, 1] = 25;
Similarly, the following example gets the value of a particular array element and assigns it to
variable elementValue.
int elementValue = array5[2, 1];
The following code example initializes the array elements to default values (except for jagged
arrays).
int[,] array6 = new int[10, 10];
Jagged Arrays
A jagged array is an array whose elements are arrays, possibly of different sizes. A jagged array
is sometimes called an "array of arrays." The following examples show how to declare, initialize,
and access jagged arrays.
The following is a declaration of a single-dimensional array that has three elements, each of which
is a single-dimensional array of integers:
int[][] jaggedArray = new int[3][];
Before you can use jaggedArray, its elements must be initialized. You can initialize the elements
like this:
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];
Each of the elements is a single-dimensional array of integers. The first element is an array of 5
integers, the second is an array of 4 integers, and the third is an array of 2 integers.
It is also possible to use initializers to fill the array elements with values, in which case you do not
need the array size. For example:
jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };
45
You can also initialize the array upon declaration like this:
int[][] jaggedArray2 = new int[][]
{
new int[] { 1, 3, 5, 7, 9 },
new int[] { 0, 2, 4, 6 },
new int[] { 11, 22 }
};
You can use the following shorthand form. Notice that you cannot omit the new operator from the
elements initialization because there is no default initialization for the elements:
int[][] jaggedArray3 =
{
new int[] { 1, 3, 5, 7, 9 },
new int[] { 0, 2, 4, 6 },
new int[] { 11, 22 }
};
A jagged array is an array of arrays, and therefore its elements are reference types and are
initialized to null.
You can access individual array elements like these examples:
// Assign 77 to the second element ([1]) of the first array ([0]):
jaggedArray3[0][1] = 77;
// Assign 88 to the second element ([1]) of the third array ([2]):
jaggedArray3[2][1] = 88;
It's possible to mix jagged and multidimensional arrays. The following is a declaration and
initialization of a single-dimensional jagged array that contains three two-dimensional array
elements of different sizes. For more information, see Multidimensional Arrays.
int[][,] jaggedArray4 = new int[3][,]
{
new int[,] { {1,3}, {5,7} },
new int[,] { {0,2}, {4,6}, {8,10} },
new int[,] { {11,22}, {99,88}, {0,9} }
};
You can access individual elements as shown in this example, which displays the value of the
element [1,0] of the first array (value 5):
System.Console.Write("{0}", jaggedArray4[0][1, 0]);
46
The method Length returns the number of arrays contained in the jagged array. For example,
assuming you have declared the previous array, this line:
System.Console.WriteLine(jaggedArray4.Length);
returns a value of 3.
Example
This example builds an array whose elements are themselves arrays. Each one of the array
elements has a different size.
class ArrayTest
{
static void Main()
{
// Declare the array of two elements.
int[][] arr = new int[2][];
// Initialize the elements.
arr[0] = new int[5] { 1, 3, 5, 7, 9 };
arr[1] = new int[4] { 2, 4, 6, 8 };
// Display the array elements.
for (int i = 0; i < arr.Length; i++)
{
System.Console.Write("Element({0}): ", i);
for (int j = 0; j < arr[i].Length; j++)
{
System.Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " ");
}
System.Console.WriteLine();
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
47
Course Materials:
https://docs.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/
https://www.w3schools.com/cs/cs_variables.asp
https://www.tutorialsteacher.com/csharp/csharp-data-types
https://ecomputernotes.com/csharp/csharp-libraries/console-input-output
https://www.vskills.in/certification/tutorial/the-if-and-switch-statement/
https://www.studytonight.com/post/csharp-control-statements
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/singledimensional-arrays
https://docs.microsoft.com/en-us/dotnet/csharp/programmingguide/arrays/multidimensional-arrays
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/jaggedarrays
Activities/Assessments:
1. Write a C# program to check whether the given number is armstrong number or
not.Armstrong Number in C#: A positive number is called armstrong number if it is
equal to the sum of cubes of its digits for example 0, 1, 153, 370, 371, 407 etc.
48
Module 3
Overview:
This module provides the detailed discussion with sample programs of the Object
oriented approach of C# programming. The four general characteristics, Inheritance,
Encapsulation, Abstraction and Polymorphism are presented with sample programs for better
learning and application.
Module Objectives:
After successful Completion of this module, you should be able to:
• Learn the basic concepts of Object-Oriented Programming
• Discuss each characteristic of the Object-Oriented Programming
• Know and understand each characteristic with examples
• Apply the OOP concepts into application development program
49
Object-Oriented Programming
Object-oriented programming (OOP) is the core ingredient of the .NET framework. OOP is so
important that, before embarking on the road to .NET, you must understand its basic principles
and terminology to write even a simple program. The fundamental idea behind OOP is to combine
into a single unit both data and the methods that operate on that data; such units are called an
object. All OOP languages provide mechanisms that help you implement the object-oriented
model. They are encapsulation, inheritance, polymorphism and reusability. Let's now take a brief
look at these concepts.
Advantages of OOPS:
• OOP offers easy to understand and a clear modular structure for programs.
• Objects created for Object-Oriented Programs can be reused in other programs. Thus it
saves significant development cost.
• Large programs are difficult to write, but if the development and designing team follow
OOPS concept then they can better design with minimum flaws.
• It also enhances program modularity because every object exists independently.
Comparison of OOPS with other programming styles with help of an Example
Let's understand with example how OOPs is different than other programming approaches.
Programming languages can be classified into 3 primary types
1. Unstructured Programming Languages: The most primitive of all programming
languages having sequentially flow of control. Code is repeated through out the program
2. Structured Programming Languages: Has non-sequentially flow of control. Use of
functions allows for re-use of code.
3. Object Oriented Programming: Combines Data & Action Together.
Object-oriented programming (OOP) is the core ingredient of the .NET framework. OOP is so
important that, before embarking on the road to .NET, you must understand its basic principles
and terminology to write even a simple program. The fundamental idea behind OOP is to
combine into a single unit both data and the methods that operate on that data; such units are
called an object. All OOP languages provide mechanisms that help you implement the objectoriented model. They are encapsulation, inheritance, polymorphism and reusability. Let's now
take a brief look at these concepts.
Classes and Objects
Classes are special kinds of templates from which you can create objects. Each object contains
data and methods to manipulate and access that data. The class defines the data and the
functionality that each object of that class can contain.
A class declaration consists of a class header and body. The class header includes attributes,
modifiers, and the class keyword. The class body encapsulates the members of the class, that
are the data members and member functions. The syntax of a class declaration is as follows:
Attributes accessibility modifiers class identifier: baselist { body }
Attributes provide additional context to a class, like adjectives; for example the Serializable
attribute. Accessibility is the visibility of the class. The default accessibility of a class is internal.
50
Private is the default accessibility of class members. The following table lists the accessibility
keywords;
Keyword
Description
public
Public class is visible in the current and referencing
assembly.
private
Visible inside current class.
protected
Visible inside current and derived class.
Internal
Visible inside containing assembly.
Internal
protected
Visible inside containing assembly and descendent of
thecurrent class.
Modifiers refine the declaration of a class. The list of all modifiers defined in the table are as
follows;
Modifier
Description
sealed
Class can't be inherited by a derived class.
static
Class contains only static members.
unsafe
The class that has some unsafe construct likes pointers.
Abstract
The instance of the class is not created if the Class is
abstract.
The baselist is the inherited class. By default, classes inherit from the System.Object type. A
class can inherit and implement multiple interfaces but doesn't support multiple inheritances.
Step-by-step Tutorial for Creating a Class
1. Open Visual Studio from start menu.
2. Go to "File" > "New" > "Project...", select "Console Application" in the right pane and
provide the name "oops" for the project.
3. Then in the Solution Explorer, you will notice some files that are automatically created
as,
51
4. You can also write your own code in the default program.cs file that is created but it is a
good programming practice to create a new class.
5. For adding a new class, right-click over the project name (oops) in the Solution Explorer,
then click "Add" > "Class". Give the name to the class "customer" as in the following;
52
When you open the customer.cs class. you will find some default-generated code as in the
following,
1. using System;
2. using System.Collections.Generic;
3. using System.Linq;
4. using System.Text;
5.
6. namespace oops
7. {
8.
class customer
9.
{
10. }
11. }
Note
The C# console application project must require a single entry point Main () function that is
already generated in the program class. For example if you add a new customer class and want
to define one or more Main () entry points here then .NET will throw an error of multiple entry
points. So it is advisable to delete or exclude the program.cs file from the solution.
So here in this example the customer class defines fields such as CustID, Name and Address to
hold information about a particular customer. It might also define some functionality that acts
upon the data stored in these fields.
1. using System;
2.
3. namespace oops
4. {
5.
class customer
6.
{
7.
// Member Variables
8.
public int CustID;
9.
public string Name;
10.
public string Address;
11.
12.
//constuctor for initializing fields
13.
customer()
14.
{
15.
CustID=1101;
16.
Name="Tom";
17.
Address="USA";
18.
}
19.
20.
//method for displaying customer records (functionality)
21.
public void displayData()
22.
{
53
23.
Console.WriteLine("Customer="+CustID);
24.
Console.WriteLine("Name="+Name);
25.
Console.WriteLine("Address="+Address);
26.
}
27.
// Code for entry point
28. }
29. }
At line 9, we are defining a constructor of the customer class for initializing the class member
fields. The constructor is a special function that is automatically called when the customer class
object is created (instantiated). And at line 11 we are printing these fields to the console by
creating a user defined method displayData().
You can then instantiate an object of this class to represent one specific customer, set the field
value for that instance and use its functionality, as in:
1. class customer
2. {
3.
// class members code
4.
5.
//Entry point
6.
static void Main(string[] args)
7.
{
8.
// object instantiation
9.
customer obj = new customer();
10.
11.
//Method calling
12.
obj.displayData();
13.
14.
//fields calling
15.
Console.WriteLine(obj.CustID);
16.
Console.WriteLine(obj.Name);
17.
Console.WriteLine(obj.Address);
18. }
19. }
Here you use the keyword new to declare the customer class instance. This keyword creates
the object and initializes it. When you create an object of the customer class, the .NET
framework IDE provides a special feature called Intellisense that provides access to all the class
member fields and functions automatically. This feature is invoked when the "." operator is put
right after the object, as in the following;
54
Image 1.1 Intellisense feature
Normally, as the program grows in size and the code becomes more complex, the Intellisense
feature increases the convenience for the programmer by showing all member fields, properties
and functions.
Multiple Class Declaration
Sometimes circumstances require multiple classes to be declared in a single namespace. So in
that case it is not mandatory to add a separate class to the solution, instead you can attach the
new class into the existing program.cs or another one as in the following;
1. using System;
2.
3. namespace oops
4. {
5.
class Program
6.
{
7.
8.
public void MainFunction()
9.
{
10.
Console.WriteLine("Main class");
11.
}
12.
static void Main(string[] args)
13.
{
14.
//main class instance
15.
Program obj = new Program();
16.
obj.MainFunction();
17.
18.
//other class instace
55
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37. }
demo dObj=new demo();
dObj.addition();
}
}
class demo
{
int x = 10;
int y = 20;
int z;
public void addition()
{
z = x + y;
Console.WriteLine("other class in Namespace");
Console.WriteLine(z);
}
}
Here in this example, we are creating an extra class "demo" in the program.cs file at line 12 and
finally we are instantiating the demo class with the program class inside the Main() entry in lines
6 to 11. So it doesn't matter how many classes we are defining in a single assembly.
Partial classes
Typically, a class will reside entirely in a single file. However, in situations where multiple
developers need access to the same class, then having the class in multiple files can be
beneficial. The partial keywords allow a class to span multiple source files. When compiled, the
elements of the partial types are combined into a single assembly.
There are some rules for defining a partial class as in the following;
•
•
•
A partial type must have the same accessibility.
Each partial type is preceded with the "partial" keyword.
If the partial type is sealed or abstract then the entire class will be sealed and abstract.
In the following example we are adding two files, partialPart1.cs and partialPart2.cs, and declare
a partial class, partialclassDemo, in both classes.
partialPart1.cs
1. using System;
2.
3. namespace oops
4. {
5.
public partial class partialclassDemo
6.
{
56
7.
public void method1()
8.
{
9.
Console.WriteLine("method from part1 class");
10.
}
11. }
12. }
partialPart2.cs
1. using System;
2.
3. namespace oops
4. {
5.
public partial class partialclassDemo
6.
{
7.
public void method2()
8.
{
9.
Console.WriteLine("method from part2 class");
10.
}
11. }
12. }
And finally we are creating an instance of the partialclassDemo in the program.cs file as the
following:
Program.cs
1. using System;
2.
3. namespace oops
4. {
5.
class Program
6.
{
7.
static void Main(string[] args)
8.
{
9.
//partial class instance
10.
partialclassDemo obj = new partialclassDemo();
11.
obj.method1();
12.
obj.method2();
13.
}
14. }
15. }
57
Static classes
A static class is declared using the "static" keyword. If the class is declared as static then the
compiler never creates an instance of the class. All the member fields, properties and functions
must be declared as static and they are accessed by the class name directly not by a class
instance object.
1. using System;
2.
3. namespace oops
4. {
5.
static class staticDemo
6.
{
7.
//static fields
8.
static int x = 10, y;
9.
10.
//static method
11.
static void calcute()
12.
{
13.
y = x * x;
14.
Console.WriteLine(y);
15.
}
16.
static void Main(string[] args)
17.
{
18.
//function calling directly
19.
staticDemo.calcute();
20.
}
21. }
22. }
Creating and Accessing Class Component Library
.NET provides the capability of creating libraries (components) of a base application rather than
an executable (".exe"). Instead the library project's final build version will be ".DLL" that can be
referenced from other outside applications to expose its entire functionality.
Step-by-step tutorial
First create a class library based application as,
58
Then we are implementing a math class library that is responsible of calculating square root and
the addition of two numbers as:
1. using System;
2.
3. namespace LibraryUtil
4. {
5.
public class MathLib
6.
{
7.
public MathLib() { }
8.
9.
public void calculareSum(int x, int y)
10.
{
11.
int z = x + y;
12.
Console.WriteLine(z);
13.
}
14.
15.
public void calculareSqrt(double x)
16.
{
17.
double z = Math.Sqrt(x);
18.
Console.WriteLine(z);
19.
}
20. }
21. }
59
Build this code and you will notice that a DLL file was created, not an executable, in the root
directory of the application (path = D:\temp\LibraryUtil\LibraryUtil\bin\Debug\ LibraryUtil.dll).
Now create another console based application where you utilize all the class library's
functionality.
Then you have to add the class library dll file reference to access the declared class in the
library dll. (Right-click on the Reference then "Add reference" then select the path of the dll file.)
When you add the class library reference then you will notice in the Solution Explorer that a new
LibraryUtil is added as in the following;
Now add the namespace of the class library file in the console application and create the
instance of the class declared in the library as in the following;
1. using System;
2. using LibraryUtil; // add library namespace
3. namespace oops
4. {
5.
public class LibraryClass
6.
{
7.
static void Main()
8.
{
9.
//library class instance
10.
MathLib obj = new MathLib();
11.
12.
//method populate
13.
obj.calculareSum(2, 5);
14.
obj.calculareSqrt(25);
15.
}
16. }
17. }
60
Constructor and Destructor
A constructor is a specialized function that is used to initialize fields. A constructor has the same
name as the class. Instance constructors are invoked with the new operator and can't be called
in the same manner as other member functions. There are some important rules pertaining to
constructors as in the following;
•
•
•
•
•
•
Classes with no constructor have an implicit constructor called the default constructor,
that is parameterless. The default constructor assigns default values to fields.
A public constructor allows an object to be created in the current assembly or
referencing assembly.
Only the extern modifier is permitted on the constructor.
A constructor returns void but does not have an explicitly declared return type.
A constructor can have zero or more parameters.
Classes can have multiple constructors in the form of default, parameter or both.
The following example shows one constructor for a customer class.
1. using System;
2. namespace oops
3. {
4.
class customer
5.
{
6.
// Member Variables
7.
public string Name;
8.
9.
//constuctor for initializing fields
10.
public customer(string fname, string lname)
11.
{
12.
Name= fname +" "+ lname;
13.
}
14.
//method for displaying customer records
15.
public void AppendData()
16.
{
17.
Console.WriteLine(Name);
18.
}
19.
//Entry point
20.
static void Main(string[] args)
21.
{
22.
// object instantiation
23.
customer obj = new customer("Barack", "Obama");
24.
25.
//Method calling
26.
obj.AppendData();
27.
}
28. }
29. }
61
Note
The moment a new statement is executed, the default constructor is called.
Static Constructor
A constructor can be static. You create a static constructor to initialize static fields. Static
constructors are not called explicitly with the new statement. They are called when the class is
first referenced. There are some limitations of the static constructor as in the following;
•
•
•
Static constructors are parameterless.
Static constructors can't be overloaded.
There is no accessibility specified for Static constructors.
In the following example the customer class has a static constructor that initializes the static
field and this constructor is called when the class is referenced in the Main () at line 26 as in the
following:
1. using System;
2. namespace oops
3. {
4.
class customer
5.
{
6.
// Member Variables
7.
static private int x;
8.
9.
//constuctor for static initializing fields
10.
static customer()
11.
{
12.
x = 10;
13.
}
14.
//method for get static field
15.
static public void getData()
16.
{
17.
Console.WriteLine(x);
18.
}
19.
//Entry point
20.
static void Main(string[] args)
21.
{
22.
//static Method calling
23.
customer.getData();
24.
}
25. }
26. }
62
Destructors
The purpose of the destructor method is to remove unused objects and resources. Destructors
are not called directly in the source code but during garbage collection. Garbage collection is
nondeterministic. A destructor is invoked at an undetermined moment. More precisely a
programmer can't control its execution; rather it is called by the Finalize () method. Like a
constructor, the destructor has the same name as the class except a destructor is prefixed with
a tilde (~). There are some limitations of destructors as in the following;
•
•
•
•
Destructors are parameterless.
A Destructor can't be overloaded.
Destructors are not inherited.
Destructors can cause performance and efficiency implications.
The following implements a destructor and dispose method. First of all we are initializing the
fields via constructor, doing some calculations on that data and displaying it to the console. But
at line 9 we are implementing the destructor that is calling a Dispose() method to release all the
resources.
1. using System;
2. namespace oops
3. {
4.
class customer
5.
{
6.
// Member Variables
7.
public int x, y;
8.
//constuctor for initializing fields
9.
customer()
10.
{
11.
Console.WriteLine("Fields inititalized");
12.
x = 10;
13.
}
14.
//method for get field
15.
public void getData()
16.
{
17.
y = x * x;
18.
Console.WriteLine(y);
19.
}
20.
//method to release resource explicitly
21.
public void Dispose()
22.
{
23.
Console.WriteLine("Fields cleaned");
24.
x = 0;
25.
y = 0;
26.
}
27.
//destructor
28.
~customer()
29.
{
63
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41. }
42. }
Dispose();
}
//Entry point
static void Main(string[] args)
{
//instance created
customer obj = new customer();
obj.getData();
}
At line 12 when the instance is created, fields are initialized but it is not necessary that at the
same time the destructor is also called. Its calling is dependent on garbage collection. If you
want to see the destructor being called into action then put a breakpoint (by F9) at line 10 and
compile the application. The CLR indicates its execution at the end of the program by
highlighting line 10 using the yellow color.
Method Overloading
Method overloading allows multiple implementations of the same function in a class.
Overloaded methods share the same name but have a unique signature. The number of
parameters, types of parameters or both must be different. A function can't be overloaded on
the basis of a different return type alone.
1. using System;
2. namespace oops
3. {
4.
class funOverload
5.
{
6.
public string name;
7.
8.
//overloaded functions
9.
public void setName(string last)
10.
{
11.
name = last;
12.
}
13.
14.
public void setName(string first, string last)
15.
{
16.
name = first + "" + last;
17.
}
18.
19.
public void setName(string first, string middle, string last)
64
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34. }
35. }
{
name = first + "" + middle + "" + last;
}
//Entry point
static void Main(string[] args)
{
funOverload obj = new funOverload();
obj.setName("barack");
obj.setName("barack "," obama ");
obj.setName("barack ","hussian","obama");
}
At lines 3, 4 and 5 we are defining three methods with the same name but with different
parameters. In the Main (), the moment you create an instance of the class and call the
functions setName() via obj at lines 7, 8 and 9 then intellisense will show three signatures
automatically.
Method Overriding
Overriding can be defined as: being able to change or augment the behavior of methods in
classes, known as overriding their logic; it is one of the most powerful aspects of Object Oriented
Programming.
Suppose you have a Phone, no please don’t suppose everyone has a phone today, although
some people even have more than one. Okay leave it, so if you have phone:
Then there must be ring facility in it:
65
Now your phone can be of any type, like it can be cellular, satellite or landline, these all types of
phones will also have the same or a different functionality (based on their attribute).
Now whenever you receive a call, the caller doesn’t know whether you have a cellular phone,
landline phone or anything else, he/she just calls you and according to that call operation your
phone rings. In the case of method overriding, your phone works as a class and the ring is the
functionality.
66
Keywords in Method Overriding
There are the following 3 types of keywords used in C# for method overriding:
Virtual Keyword
It tells the compiler that this method can be overridden by derived classes.
1. public virtual int myValue()
2. {
3.
4.
5.
6. }
Override Keyword
In the subclass, it tells the compiler that this method is overriding the same named method in
the base class.
1. public override int myValue()
2. {
3.
4.
5.
6. }
Base Keyword
In the subclass, it calls the base class method for overriding functionality.
1. base.myValue();
67
Method Overriding Example
1. using System;
2. using System.Collections.Generic;
3. using System.Linq;
4. using System.Text;
5. namespace Hello_Word
6. {
7.
class baseClass
8.
{
9.
public virtual void Greetings()
10.
{
11.
Console.WriteLine("baseClass Saying Hello!");
12.
}
13. }
14. class subClass : baseClass
15. {
16.
public override void Greetings()
17.
{
18.
base.Greetings();
19.
Console.WriteLine("subClass Saying Hello!");
20.
}
21. }
22. class Program
23. {
24.
static void Main(string[] args)
25.
{
26.
baseClass obj1 = new subClass();
27.
obj1.Greetings();
28.
Console.ReadLine();
29.
}
30. }
31. }
68
An output window is showing that baseClass will get called first and then subclass. If we make
certain changes in this code like:
1. base.Greetings();
2. Console.WriteLine("subClass Saying Hello!"); // current scenario
After making a few modifications as in the following:
1. Console.WriteLine("subClass Saying Hello!");
2. base.Greetings(); // after modifications
Now our output will be like this:
If we remove "base.Greetings();" then the compiler will not call the baseclass as in the following:
1. using System;
2. using System.Collections.Generic;
3. using System.Linq;
4. using System.Text;
5. namespace Hello_Word
6. {
7.
class baseClass
8.
{
9.
public virtual void Greetings()
10.
{
11.
Console.WriteLine("baseClass Saying Hello!");
12.
}
13. }
14. class subClass : baseClass
15. {
16.
public override void Greetings()
17.
{
18.
Console.WriteLine("subClass Saying Hello!");
69
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31. }
// base.Greetings();
}
}
class Program
{
static void Main(string[] args)
{
baseClass obj1 = new subClass();
obj1.Greetings();
Console.ReadLine();
}
}
Now making some other changes, like placing:
1. baseClass obj1 = new baseClass();
2. obj1.Greetings();
Instead of:
1. baseClass obj1 = new subClass();
2. obj1.Greetings();
Now let’s check the output window, what’s its showing now:
70
So as you are seeing that now its calling only the baseClass. So now I guess you will be a little
closer to the method overriding functionality.
Encapsulation
Encapsulation is the mechanism that binds together the code and the data it manipulates, and
keeps both safe from outside interference and misuse. In OOP, code and data may be combined
in such a way that a self-contained box is created. When code and data are linked together in this
way, an object is created and encapsulation exists.
Within an object, code, data or both may be private or public to that object. Private code is known
to and accessible only by another part of the object, that is private code or data may not be
accessible by a piece of the program that exists outside the object. When the code and data is
public, other portions of your program may access it even though it is defined within an object.
1. using System;
2. namespace oops
3. {
4.
class Encapsulation
5.
{
6.
/// <summary>
7.
/// Every member Variable and Function of the class are bind
8.
/// with the Encapsulation class object only and safe with
9.
/// the outside inference
10.
/// </summary>
11.
12.
// Encapsulation Begin
71
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40. }
41. }
int x;
//class constructor
public Encapsulation(int iX)
{
this.x = iX;
}
//calculating the square
public void MySquare()
{
int Calc = x * x;
Console.WriteLine(Calc);
}
// End of Encapsulation
//Entry point
static void Main(string[] args)
{
//instance created
customer obj = new customer(20);
obj. MySquare();
}
Why do we need Encapsulation
The need of encapsulation is to protect or prevent the code (data) from accidental corruption due
to the silly little errors that we are all prone to make. In Object oriented programming data is
treated as a critical element in the program development and data is packed closely to the
functions that operate on it and protects it from accidental modification from outside functions.
Encapsulation provides a way to protect data from accidental corruption. Rather than defining the
data in the form of public, we can declare those fields as private. The Private data are manipulated
indirectly by two ways. Let us see some example programs in C# to demonstrate Encapsulation
by those two methods. The first method is using a pair of conventional accessor and mutator
methods. Another one method is using a named property. Whatever be the method our aim is to
use the data without any damage or change.
72
Encapsulation Using Accessors and Mutators
Let us see an example of Department class. To manipulate the data in that class (String
departname) we define an accessor (get method) and mutator (set method).
1. using system;
2. public class Department {
3.
private string departname;.......
4.
// Accessor.
5.
public string GetDepartname() {
6.
return departname;
7.
}
8.
// Mutator.
9.
public void SetDepartname(string a) {
10.
departname = a;
11. }
12. }
Like the above way we can protect the private data from the outside world. Here we use two
separate methods to assign and get the required data.
1. public static int Main(string[] args) {
2.
Department d = new Department();
3.
d.SetDepartname("ELECTRONICS");
4.
Console.WriteLine("The Department is :" + d.GetDepartname());
5.
return 0;
6. }
In the above example we can't access the private data departname from an object instance. We
manipulate the data only using those two methods.
Encapsulation Using Properties
Properties are a new language feature introduced with C#. Only a few languages support this
property. Properties in C# helps in protect a field in a class by reading and writing to it. The first
method itself is good but Encapsulation can be accomplished much smoother with properties.
Now let's see an example.
1. using system;
2. public class Department {
3.
private string departname;
4.
public string Departname {
5.
get {
6.
return departname;
7.
}
73
8.
set {
9.
departname = value;
10.
}
11. }
12. }
13. public class Departmentmain {
14. public static int Main(string[] args) {
15.
Department d = new Department();
16.
d.departname = "Communication";
17.
Console.WriteLine("The Department is :{0}", d.Departname);
18.
return 0;
19. }
20. }
From the above example we see the usage of Encapsulation by using properties. The property
has two accessor get and set. The get accessor returns the value of the some property field. The
set accessor sets the value of the some property field with the contents of "value". Properties can
be made read-only. This is accomplished by having only a get accessor in the property
implementation.
Read Only Property
1. using system;
2. public class ReadDepartment {
3.
private string departname;
4.
public ReadDepartment(string avalue) {
5.
departname = avalue;
6.
}
7.
public string Departname {
8.
get {
9.
return departname;
10.
}
11. }
12. }
13. public class ReadDepartmain {
14. public static int Main(string[] args) {
15.
ReadDepartment d = new ReadDepartment("COMPUTERSCIENCE");
16.
Console.WriteLine("The Department is: {0}", d.Departname);
17.
return 0;
18. }
19. }
In the above example we see how to implement a read-only property. The class ReadDepartment
has a Departname property that only implements a get accessor. It leaves out the set accessor.
This particular class has a constructor, which accepts a string parameter. The Main method of
the ReadDepartmain class creates a new object named d. The instantiation of the d object uses
74
the constructor of the ReadDepartment that takes a string parameter. Since the above program
is read-only, we cannot set the value to the field departname and we only read or get the value of
the data from the field. Properties can be made also Write-only. This is accomplished by having
only a set accessor in the property implementation.
Write Only Property
1. using system;
2. public class WriteDepartment {
3.
private string departname;
4.
public string Departname {
5.
set {
6.
departname = value;
7.
Console.WriteLine("The Department is :{0}", departname);
8.
}
9.
}
10. }
11. public class WriteDepartmain {
12. public static int Main(string[] args) {
13.
WriteDepartment d = new WriteDepartment();
14.
d.departname = "COMPUTERSCIENCE";
15.
return 0;
16. }
17. }
In the above example we see how to implement a Write-only property. The class WriteDepartment
has now has a Departname property that only implements a set accessor. It leaves out the get
accessor. The set accessor method is varied a little by it prints the value of the departname after
it is assigned.
Inheritance
Inheritance is the process by which one object can acquire the properties of another object.
Inheritance is a "is a kind of" relationship and it supports the concept of classification in which an
object needs only define those qualities that make it unique within the class. Inheritance involves
a base class and a derived class. The derived class inherits from the base class and also can
override inherited members as well as add new members to extend the base class.
A base type represents the generalization, whereas a derived type represents a specification of
an instance. Such as Employees that can have diverse types, such as hourly, salaried and
temporary so in that case Employees is the general base class and hourly, salaried and temporary
employee are specialized derived classes.
Classes can inherit from a single class and one or more interfaces. When inheriting from a class,
the derived class inherits the members including the code of the base class. The important point
to remember is that Constructors and Destructors are not inherited from the base class.
75
The syntax of inheritance is as in the following;
Class derivedClass : baseClass, Iterface1, Interface2 { body }
For example we are defining two classes, Father and Child. You notice at line 7, we are
implementing inheritance by using a colon (:); at this moment all the properties belonging to the
Father Class is accessible to the Child class automatically.
1. using System;
2. namespace oops
3. {
4.
//Base Class
5.
public class Father
6.
{
7.
public void FatherMethod()
8.
{
9.
Console.WriteLine("this property belong to Father");
10.
}
11. }
12.
13. //Derived class
14. public class Child : Father
15. {
16.
public void ChildMethod()
17.
{
18.
Console.WriteLine("this property belong to Child");
19.
}
20. }
21. class Inheritance
22. {
76
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35. }
36. }
//Entry point
static void Main(string[] args)
{
Father fObj = new Father();
fObj.FatherMethod();
//Here Child object can access both class methods
Child cObj = new Child();
cObj.FatherMethod();
cObj.ChildMethod();
}
At line 11 , the Intellisense only shows the Father class functions but at line 15 to 16 the Child
class object is able to access both class methods as in the following.
We can create a class in the VB.Net language or another .NET supported language and can
inherit them in a C# .Net class and vice versa. But a class developed in C++ or other
unmanaged environment can't be inherited in .NET.
Note
Cross-language and multiple inheritance is not supported by .NET.
Accessibility
Accessibility sets the visibility of the member to outside assemblies or derived types. The
following table describes member accessibility;
Modifiers
Outside Assembly
Derived Class
private
No
No
public
Yes
Yes
protected
No
No
internal
Yes ( this assembly only)
Yes ( this assembly
only)
internal protected
Yes ( this assembly only)
Yes
77
Constructor in Inheritance
Constructors in a base class are not inherited in a derived class. A derived class has a base
portion and derived portion. The base portion initializes the base portion, and the constructor of
the derived class initializes the derived portion.
The following is the syntax of a constructor in inheritance;
Accessibility modifier classname(parameterlist1) : base(parameterlist2) { body }
So the base keyword refers to the base class constructor, while parameterlist2 determines which
overloaded base class constructor is called.
In the following example, the Child class's constructor calls the single-argument constructor of the
base Father class;
1. using System;
2. namespace oops
3. {
4.
//Base Class
5.
public class Father
6.
{
7.
8.
//constructor
9.
public Father()
10.
{
11.
Console.WriteLine("Father class constructor");
12.
}
13.
14.
public void FatherMethod()
15.
{
16.
Console.WriteLine("this property belong to Father");
17.
}
18. }
19.
20. //Derived class
21. public class Child : Father
22. {
23.
public Child()
24.
: base()
25.
{
26.
Console.WriteLine("child class constructor");
27.
}
28.
public void ChildMethod()
29.
{
30.
Console.WriteLine("this property belong to Child");
31.
}
32. }
78
33. class Inheritance
34. {
35.
//Entry point
36.
static void Main(string[] args)
37.
{
38.
//Here Child object can access both class methods
39.
Child cObj = new Child();
40.
cObj.FatherMethod();
41.
cObj.ChildMethod();
42.
Console.ReadKey();
43.
}
44. }
45. }
At line 4, we are defining a base Father Class constructor and in the derived class Child, at line 8
we are initializing it explicitly via base keyword. If we pass any parameter in the base class
constructor then we have to provide them in the base block of the child class constructor.
Virtual Methods
By declaring a base class function as virtual, you allow the function to be overridden in any derived
class. The idea behind a virtual function is to redefine the implementation of the base class
method in the derived class as required. If a method is virtual in the base class then we have
to provide the override keyword in the derived class. Neither member fields nor static functions
can be declared as virtual.
1. using System;
2. namespace oops
3. {
4.
class myBase
5.
{
6.
//virtual function
7.
public virtual void VirtualMethod()
8.
{
9.
Console.WriteLine("virtual method defined in the base class");
10.
}
11. }
12.
13. class myDerived : myBase
14. {
15.
// redifing the implementation of base class method
16.
public override void VirtualMethod()
17.
{
18.
Console.WriteLine("virtual method defined in the Derive class");
19.
}
20. }
21. class virtualClass
79
22. {
23.
static void Main(string[] args)
24.
{
25.
// class instance
26.
new myDerived().VirtualMethod();
27.
Console.ReadKey();
28.
}
29. }
30. }
Hiding Methods
If a method with the same signature is declared in both base and derived classes, but the methods
are not declared as virtual and overriden respectively, then the derived class version is said to
hide the base class version. In most cases, you would want to override methods rather than hide
them. Otherwise .NET automatically generates a warning.
In the following example, we are defining a VirutalMethod() in the myBase class but not overriding
it in the derived class, so in that case the compiler will generate a warning. The compiler will
assume that you are hiding the base class method. So to overcome that problem, if you prefix the
new keyword in the derived class method then the compiler will prefer the most derived version
method. You can still access the base class method in the derived class by using the base
keyword.
1. using System;
2. namespace oops
3. {
4.
class myBase
5.
{
6.
//virtual function
7.
public virtual void VirtualMethod()
8.
{
9.
Console.WriteLine("virtual method defined in the base class");
10.
}
11. }
12.
13. class myDerived : myBase
14. {
15.
// hiding the implementation of base class method
16.
public new void VirtualMethod()
17.
{
18.
Console.WriteLine("virtual method defined in the Derive class");
19.
20.
//still access the base class method
21.
base.VirtualMethod();
22.
}
80
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
}
class virtualClass
{
static void Main(string[] args)
{
// class instance
new myDerived().VirtualMethod();
Console.ReadKey();
}
}
33.
}
Abstraction
Abstraction is "To represent the essential feature without representing the background details."
Abstraction lets you focus on what the object does instead of how it does it. Abstraction provides
you a generalized view of your classes or objects by providing relevant information. It is the
process of hiding the working style of an object and showing the information of an object in an
understandable
manner.
Real-world Example of Abstraction
Suppose you have an object Mobile Phone.
Suppose you have 3 mobile phones as in the following:
Nokia 1400 (Features: Calling, SMS)
Nokia 2700 (Features: Calling, SMS, FM Radio, MP3, Camera)
Black Berry (Features:Calling, SMS, FM Radio, MP3, Camera, Video Recording, Reading Emails)
Abstract information (necessary and common information) for the object "Mobile Phone" is that
it makes a call to any number and can send SMS.
So that, for a mobile phone object you will have the abstract class as in the following,
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
abstract class MobilePhone {
public void Calling();
public void SendSMS();
}
public class Nokia1400: MobilePhone {}
public class Nokia2700: MobilePhone {
public void FMRadio();
public void MP3();
public void Camera();
}
public class BlackBerry: MobilePhone {
81
12.
13.
14.
15.
16.
17.
public void FMRadio();
public void MP3();
public void Camera();
public void Recording();
public void ReadAndSendEmails();
}
Abstraction means putting all the variables and methods in a class that are necessary.
For example: Abstract class and abstract method.
Abstraction is a common thing.
Example
If somebody in your college tells you to fill in an application form, you will provide your details, like
name, address, date of birth, which semester, percentage you have etcetera.
If some doctor gives you an application to fill in the details, you will provide the details, like name,
address, date of birth, blood group, height and weight.
See in the preceding example what is in common?
Age, name and address, so you can create a class that consists of the common data. That is
called an abstract class.
That class is not complete and it can be inherited by other classes.
Abstract Classes
C# allows both classes and functions to be declared abstract using the abstract keyword. You
can't create an instance of an abstract class. An abstract member has a signature but no
function body and they must be overridden in any non-abstract derived class. Abstract classes
exist primarily for inheritance. Member functions, properties and indexers can be abstract. A
class with one or more abstract members must be abstract as well. Static members can't be
abstract.
In this example, we are declaring an abstract class Employess with a method displayData() that
does not have an implementation. Then we are implementing the displayData() body in the
derived class. One point to be noted here is that we have to prefixe the abstract method with the
override keyword in the derived class.
1. using System;
2. namespace oops
3. {
4.
//abstract class
82
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28. }
public abstract class Employess
{
//abstract method with no implementation
public abstract void displayData();
}
//derived class
public class test : Employess
{
//abstract class method implementation
public override void displayData()
{
Console.WriteLine("Abstract class method");
}
}
class abstractClass
{
static void Main(string[] args)
{
// class instance
new test().displayData();
}
}
Sealed Classes
Sealed classes are the reverse of abstract classes. While abstract classes are inherited and are
refined in the derived class, sealed classes cannot be inherited. You can create an instance of a
sealed class. A sealed class is used to prevent further refinement through inheritance.
Suppose you are a developer of a class library and some of the classes in the class library are
extensible but other classes are not extensible so in that case those classes are marked as
sealed.
1. using System;
2. namespace oops
3. {
4.
sealed class SealedClass
5.
{
6.
void myfunv();
7.
}
8.
9.
public class test : SealedClass //wrong. will give compilation error
10. {
11. }
12. }
83
Interface
An interface is a set of related functions that must be implemented in a derived class. Members
of an interface are implicitly public and abstract. Interfaces are similar to abstract classes. First,
both types must be inherited; second, you cannot create an instance of either. Although there are
several differences as in the following;
•
•
•
•
An Abstract class can contain some implementations but an interface can't.
An Interface can only inherit other interfaces but abstract classes can inherit from other
classes and interfaces.
An Abstract class can contain constructors and destructors but an interface can't.
An Abstract class contains fields but interfaces don't.
So the question is, which of these to choose? Select interfaces because with an interface, the
derived type still can inherit from another type and interfaces are more straightforward than
abstract classes.
1. using System;
2. namespace oops
3. {
4.
// interface
5.
public interface xyz
6.
{
7.
void methodA();
8.
void methodB();
9.
}
10.
11. // interface method implementation
12. class test : xyz
13. {
14.
public void methodA()
15.
{
16.
Console.WriteLine("methodA");
17.
}
18.
public void methodB()
19.
{
20.
Console.WriteLine("methodB");
21.
}
22. }
23. class interfaceDemo
24. {
25.
static void Main(string[] args)
26.
{
27.
test obj = new test();
28.
obj.methodA();
29.
obj.methodB();
30.
}
31. }
84
32. }
An interface can be inherited from other interfaces as in the following:
1. public interface xyz
2. {
3.
void methodA();
4.
void methodB();
5. }
6.
7. public interface abc : xyz
8. {
9.
void methodC();
10. }
Polymorphism
Polymorphism is a Greek word, meaning "one name many forms". In other words, one object
has many forms or has one name with multiple functionalities. "Poly" means many and "morph"
means forms. Polymorphism provides the ability to a class to have multiple implementations
with the same name. It is one of the core principles of Object Oriented Programming after
encapsulation and inheritance. In this article, you'll learn what polymorphism is, how it works,
and how to implement polymorphism in C#.
Types of Polymorphism
There are two types of polymorphism in C#:
•
•
Static / Compile Time Polymorphism.
Dynamic / Runtime Polymorphism.
85
Static or Compile Time Polymorphism
It is also known as Early Binding. Method overloading is an example of Static Polymorphism. In
overloading, the method / function has a same name but different signatures. It is also known as
Compile Time Polymorphism because the decision of which method is to be called is made at
compile time. Overloading is the concept in which method names are the same with a different
set
of
parameters.
Here C# compiler checks the number of parameters passed and the type of parameter and make
the decision of which method to call and it throw an error if no matching method is found.
In the following example, a class has two methods with the same name "Add" but with different
input parameters (the first method has three parameters and the second method has two
parameters).
1. public class TestData
2. {
3.
public int Add(int a, int b, int c)
4.
{
5.
return a + b + c;
6.
}
7.
public int Add(int a, int b)
8.
{
9.
return a + b;
10. }
11. }
12. class Program
13. {
14. static void Main(string[] args)
15. {
16.
TestData dataClass = new TestData();
17.
int add2 = dataClass.Add(45, 34, 67);
18.
int add1 = dataClass.Add(23, 34);
86
19. }
20. }
Dynamic / Runtime Polymorphism
Dynamic / runtime polymorphism is also known as late binding. Here, the method name and the
method signature (number of parameters and parameter type must be the same and may have a
different implementation). Method overriding is an example of dynamic polymorphism.
Method overriding can be done using inheritance. With method overriding it is possible for the
base class and derived class to have the same method name and same something. The compiler
would not be aware of the method available for overriding the functionality, so the compiler does
not throw an error at compile time. The compiler will decide which method to call at runtime and
if no method is found then it throws an error.
1. public class Drawing
2. {
3.
public virtual double Area()
4.
{
5.
return 0;
6.
}
7. }
8.
9. public class Circle : Drawing
10. {
11. public double Radius { get; set; }
12. public Circle()
13. {
14.
Radius = 5;
15. }
16. public override double Area()
17. {
18.
return (3.14) * Math.Pow(Radius, 2);
19. }
20. }
21.
87
22. public class Square : Drawing
23. {
24. public double Length { get; set; }
25. public Square()
26. {
27.
Length = 6;
28. }
29. public override double Area()
30. {
31.
return Math.Pow(Length, 2);
32. }
33. }
34.
35. public class Rectangle : Drawing
36. {
37. public double Height { get; set; }
38. public double Width { get; set; }
39. public Rectangle()
40. {
41.
Height = 5.3;
42.
Width = 3.4;
43. }
44. public override double Area()
45. {
46.
return Height * Width;
47. }
48. }
49.
50. class Program
51. {
52. static void Main(string[] args)
53. {
54.
55.
Drawing circle = new Circle();
56.
Console.WriteLine("Area :" + circle.Area());
57.
58.
Drawing square = new Square();
59.
Console.WriteLine("Area :" + square.Area());
60.
61.
Drawing rectangle = new Rectangle();
62.
Console.WriteLine("Area :" + rectangle.Area());
63. }
64. }
88
The compiler requires an Area() method and it compiles successfully but the right version of the
Area() method is not being determined at compile time but determined at runtime. Finally the
overriding methods must have the same name and signature (number of parameters and type),
as the virtual or abstract method defined in the base class method and that it is overriding in the
derived
class.
A method or function of the base class is available to the child (derived) class without the use of
the "overriding" keyword. The compiler hides the function or method of the base class. This
concept is known as shadowing or method hiding. You may find the difference between overriding
and shadowing here.
Preventing Derived class from overriding virtual members
Virtual members remain “virtual” indefinitely. In other words, virtual members remain “virtual”
regardless of how many classes have been between virtual members and the class that originally
declared it. For example, if class X has the virtual method "A" and the class Y is derived from X
and the class Z is derived from Y, class Z inherits the virtual method "A" and override it.
89
1. public class X
2. {
3.
public virtual void A()
4.
{
5.
}
6. }
7. public class Y : X
8. {
9.
public override void A()
10. {
11. }
12. }
A derived class is able to stop virtual inheritance by declaring an override member as "sealed".
1. public class Y : X
2. {
3.
public sealed override void A()
4.
{
5.
}
6. }
Accessing Base class virtual member
Using the "base" keyword, the derived class is able to access the method.
1. public class X
2. {
3.
public virtual void A()
4.
{
5.
}
6. }
7. public class Y : X
8. {
9.
public override void A()
10. {
11.
base.A();
12. }
13. }
90
Course Materials:
https://www.c-sharpcorner.com/UploadFile/84c85b/object-oriented-programming-using-CSharpnet/#:~:text=C%23%20is%20an%20object%20oriented,%2C%20data%20hiding%2C%20and%
20inheritance.&text=They%20are%20encapsulation%2C%20inheritance%2C%20polymorphism
,brief%20look%20at%20these%20concepts.
https://www.c-sharpcorner.com/UploadFile/mkagrahari/introduction-to-object-orientedprogramming-concepts-in-C-Sharp/
https://www.c-sharpcorner.com/UploadFile/2072a9/method-overriding-in-C-Sharp/
https://www.c-sharpcorner.com/article/encapsulation-in-C-Sharp/
https://www.c-sharpcorner.com/UploadFile/ff2f08/understanding-polymorphism-in-C-Sharp/
Activities/Assessments:
A. This post-test is intended to gauge what you already know about the Language Basics and
Object-Oriented Programming Concepts of C#. Please answer the following questions by
encircling the letter of the correct answer.
1. What will be the output of the following code snippet?
using System;
public class emp
{
public static int age = 40;
public static int salary = 25000;
}
public class record :emp
{
new public static int salary = 50000;
static void Main(string[] args)
{
Console.WriteLine(emp.age + " " + emp.salary + "
}
}
" + salary);
a. 40, 25000, 50000
b. 40, 25000, 25000
c. 40, 50000, 50000
d. Error
2. Which of the following keyword, enables to modify the data and behavior of a base class
by replacing its member with a new derived member?
a) overloads
b) overrides
c) new
d) base
3. What will be the correct order of execution of function func1(), func2() & func3() in the
given code snippet?
class baseclass
{
public void func1() {}
public virtual void func2() {}
public virtual void func3() {}
91
}
class derivedclass :baseclass
{
new public void func1() {}
public override void func2() {}
public new void func3() {}
}
class Program
{
static void Main(string[] args)
{
baseclass b = new derivedclass();
b.func1 ();
b.func2 ();
b.func3 ();
}
}
a) func1() of derived class get executed
func2() of derived class get executed
func3() of base class get executed
b) func1() of base class get executed
func2() of derived class get executed
func3() of derived class get executed
c) func1() of derived class get executed
func2() of base class get executed
func3() of base class get executed
d) func1() of base class get executed
func2() of derived class get executed
func3() of base class get executed
4. Which of the following keywords is used to refer base class constructor to subclass
constructor?
a) this
b) static
c) base
d) extend
5. What will be the output of the following code snippet?
using System;
class sample
{
int i;
public sample(int x)
{
i = x;
Console.WriteLine("Tech");
}
}
class derived : sample
{
public derived(int x) :base(x)
{
Console.WriteLine("Beamers");
}
}
class Program
92
{
static void Main(string[] args)
{
derived k = new derived(12);
Console.ReadLine();
}
}
a) TechBeamers
b) 12 Tech
c) Beamers 12
d) Compile time error
6. What will be the output of the following code snippet?
using System;
class sample
{
int i;
public sample(int num)
{
num = 12;
int j = 12;
int val = num * j;
Console.WriteLine(val);
}
}
class sample1 : sample
{
public sample1(int a) :base(a)
{
a = 13;
int b = 13;
Console.WriteLine(a + b);
}
}
class sample2 : sample1
{
public sample2(int k) :base(k)
{
k = 24;
int o = 6 ;
Console.WriteLine(k /o);
}
}
class Program
{
public static void Main(string[] args)
{
sample2 t = new sample2(10);
Console.ReadLine();
}
}
a) 4, 26, 144
b) 26, 4, 144
c) 144, 26, 4
d) 0, 0, 0
93
7. Which of the following options represents the type of class which does not have its own
objects but acts as a base class for its subclass?
a) Static class
b) Sealed class
c) Abstract class
d) Derived class
8. What will be the output of the following code snippet?
using System;
namespace TechBeamers
{
abstract class baseclass
{
public int i;
public abstract void print();
}
class derived: baseclass
{
public int j;
public int val;
public override void print()
{
val = i + j;
Console.WriteLine(+i + "\n" + +j);
Console.WriteLine("sum is:" +val);
}
}
class Program
{
static void Main(string[] args)
{
baseclass obj = new derived();
obj.i = 2;
derived obj1 = new derived();
obj1.j = 10;
obj.print();
Console.ReadLine();
}
}
}
a) 2 10
Sum is: 12
b) 0 10
Sum is: 10
c) 2 0
Sum is: 2
d) 0 0
Sum is: 0
9. Which of the following represents a class that inherits an abstract class but it does not
define all of its functions?
a) Abstract
b) A simple class
c) Static class
d) derived class
94
10. What will be the output of the following code snippet?
using System;
namespace TechBeamers
{
public abstract class sample
{
public int i = 7;
public abstract void print();
}
class sample1: sample
{
public int j;
public override void print()
{
Console.WriteLine(i);
Console.WriteLine(j);
}
}
class Program
{
static void Main(string[] args)
{
sample1 obj = new sample1();
sample obj1 = new sample1();
obj.j = 1;
obj1.i = 8;
obj.print();
Console.ReadLine();
}
}
}
a) 0, 8
b) 1, 8
c) 1, 7
d) 7, 1
B. Application
Create a C# program that represents the
following UML class diagram. The diagram
represents public, private, and protected
attributes as well as class dependency and
inheritance.
95
Module 4
Overview:
WPF stands for Windows Presentation Foundation. It is a powerful framework for
building Windows applications. This module explains the features that you need to
understand to build WPF applications and how it brings a fundamental change in
Windows applications.
Module Objectives:
After successful Completion of this module, you should be able to:
•
•
•
Implement GUI that facilitates a customizable look and feel
Develop applications using key foundation services
Develop graphic and GUI components using WPF
96
What is WPF?
WPF, which stands for Windows Presentation Foundation, is Microsoft's latest approach to a GUI
framework, used with the .NET framework.
But what IS a GUI framework? GUI stands for Graphical User Interface, and you are probably
looking at one right now. Windows has a GUI for working with your computer, and the browser
that you are likely reading this document in has a GUI that allows you to surf the web.
A GUI framework allows you to create an application with a wide range of GUI elements, like
labels, textboxes, and other well-known elements. Without a GUI framework you would have to
draw these elements manually and handle all the user interaction scenarios like text and mouse
input. This is a LOT of work, so instead, most developers will use a GUI framework which will do
all the basic work and allow the developers to focus on making great applications.
There are a lot of GUI frameworks out there, but for .NET developers, the most interesting ones
are currently WinForms and WPF. WPF is the newest, but Microsoft is still maintaining and
supporting WinForms.
WPF is a combination of XAML (markup) and C#/VB.NET/any other .NET language. All of it can
be edited in any text editor, even Notepad included in Windows, and then compiled from the
command line. However, most developers prefer to use an IDE (Integrated Development
Environment), since it makes everything, from writing code to designing the interface and
compiling it all so much easier.
The preferred choice for a .NET/WPF IDE is Visual Studio, which costs quite a bit of money
though. Luckily, Microsoft has decided to make it easy and free for everyone to get started with
.NET and WPF, so they have created a free version of Visual Studio, called Visual Studio
Community. This version contains slightly less functionality than the real Visual Studio, but it has
everything that you need to get started learning WPF and make real applications.
WPF Architecture
Before WPF, the other user interface frameworks offered by
Microsoft such as MFC and Windows forms, were just
wrappers around User32 and GDI32 DLLs, but WPF makes
only minimal use of User32. So,
•
WPF is more than just a wrapper.
•
It is a part of the .NET framework.
•
It contains a mixture of managed and unmanaged
code.
The major components of WPF architecture are as shown in
the figure below. The most important code part of WPF are
•
Presentation Framework
•
Presentation Core
•
Milcore
97
The presentation framework and the presentation core have been written in managed
code. Milcore is a part of unmanaged code which allows tight integration with DirectX
(responsible for display and rendering). CLR makes the development process more productive
by offering many features such as memory management, error handling, etc.
Advantages
In the earlier GUI frameworks, there was no real separation between how an application looks
like and how it behaved. Both GUI and behavior were created in the same language, e.g., C# or
VB.Net which would require more effort from the developer to implement both UI and behavior
associated with it.
In WPF, UI elements are designed in XAML while behaviors can be implemented in procedural
languages such C# and VB.Net. So, it very easy to separate behavior from the designer code.
With XAML, the programmers can work in parallel with the designers. The separation between
a GUI and its behavior can allow us to easily change the look of a control by using styles and
templates.
Features
WPF is a powerful framework to create Windows application. It supports many great features,
some of which have been listed below −
Feature
Description
Control inside a Control
Allows to define a control inside another control as a content.
Data binding
Mechanism to display and interact with data between UI elements
and data object on user interface.
Media services
Provides an integrated system for building user interfaces with
common media elements like images, audio, and video.
Templates
In WPF you can define the look of an element directly with a
Template
Animations
Building interactivity and movement on user Interface
Alternative input
Supports multi-touch input on Windows 7 and above.
Direct3D
Allows to display more complex graphics and custom themes
98
Create a Simple Application
When you create an application in Visual Studio, you first create a project and a solution. For this
example, you'll create a Windows Presentation Foundation (WPF) project.
1. Open Visual Studio 2019.
2. On the start window, choose Create new project.
3. On the Create a new project screen, search for "WPF," choose WPF App (.NET
Core), and then choose Next.
99
4. At the next screen, give the project a name, HelloWPFApp, and choose Create.
Visual Studio creates the HelloWPFApp project and solution, and Solution Explorer shows the
various files. The WPF Designer shows a design view and a XAML view of MainWindow.xaml in
a split view. You can slide the splitter to show more or less of either view. You can choose to see
only the visual view or only the XAML view.
After you create the project, you can customize it. To do so,
choose Properties Window from the View menu, or press F4. Then,
you can display and change options for project items, controls, and other
items in an application.
100
Change the name of MainWindow.xaml
Let's give MainWindow a more specific name. In Solution Explorer,
on MainWindow.xaml and choose Rename. Rename the file to Greetings.xaml.
right-click
Design the user interface (UI)
If the designer is not open, select Greetings.xaml and press Shift+F7 to open the designer.
We'll add three types of controls to this application: a TextBlock control, two RadioButton controls,
and a Button control.
Add a TextBlock control
1. Press Ctrl+Q to activate the search box and type Toolbox. Choose View >
Toolbox from the results list.
2. In the Toolbox, expand the Common WPF Controls node to see the TextBlock
control.
3. Add a TextBlock control to the design surface by choosing the TextBlock item and
dragging it to the window on the design surface. Center the control near the top of
the window. In Visual Studio 2019 and later, you can use the red guidelines to center
the control.
Your window should resemble the following illustration:
101
The XAML markup should look something like the following example:
<Grid>
<TextBlock
HorizontalAlignment="Left"
Margin="387,60,0,0"
TextWrapping="Wrap"
Text="TextBlock"
VerticalAlignment="Top"/>
</Grid>
Customize the text in the text block
1. In the XAML view, locate the markup for TextBlock and change the Text attribute
from TextBox to Select a message option and then choose the Display button.
The XAML markup should look something like the following example:
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="387,60,0,0" TextWrapping="Wrap" Text="Select a message
option and then choose the Display button." VerticalAlignment="Top"/>
</Grid>
2. Center the TextBlock again if you like, and then save your changes by
pressing Ctrl+S or using the File menu item.
Next, you'll add two RadioButton controls to the form.
Add radio buttons
1. In the Toolbox, find the RadioButton control.
102
2. Add two RadioButton controls to the design surface by choosing
the RadioButton item and dragging it to the window on the design surface. Move
the buttons (by selecting them and using the arrow keys) so that the buttons appear
side by side under the TextBlock control. Use the red guidelines to align the controls.
Your window should look like this:
3. In the Properties window for the
the Name property (the property at
to HelloButton.
103
left
the
RadioButton control, change
top of the Properties window)
4. In the Properties window for the right RadioButton control,
the Name property to GoodbyeButton, and then save your changes.
change
Next, you'll add display text for each RadioButton control. The following procedure updates
the Content property for a RadioButton control.
Add display text for each radio button
1. Update
the Content attribute
for
the HelloButton and GoodbyeButton to "Hello" and "Goodbye" in the XAML. The
XAML markup should now look similar to the following example:
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="252,47,0,0" TextWrapping="Wrap" Text="Select a message
option and then choose the Display button." VerticalAlignment="Top"/>
<RadioButton
x:Name="HelloButton"
Content="Hello"
HorizontalAlignment="Left"
Margin="297,161,0,0"
VerticalAlignment="Top"/>
<RadioButton x:Name="GoodbyeButton" Content="Goodbye" HorizontalAlignment="Left" Margin="488,161,0,0"
VerticalAlignment="Top"/>
</Grid>
Set a radio button to be checked by default
In this step, we'll set HelloButton to be checked by default so that one of the two radio buttons is
always selected.
1. In the XAML view, locate the markup for HelloButton.
2. Add an IsChecked attribute and set it to True. Specifically, add IsChecked="True".
104
The XAML markup should now look similar to the following example:
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="252,47,0,0" TextWrapping="Wrap" Text="Select a message
option and then choose the Display button." VerticalAlignment="Top"/>
<RadioButton
x:Name="HelloButton"
Content="Hello"
IsChecked="True"
HorizontalAlignment="Left"
Margin="297,161,0,0" VerticalAlignment="Top"/>
<RadioButton x:Name="GoodbyeButton" Content="Goodbye" HorizontalAlignment="Left" Margin="488,161,0,0"
VerticalAlignment="Top"/>
</Grid>
The final UI element that you'll add is a Button control.
Add the button control
1. In the Toolbox, find the Button control, and then add it to the design surface under
the RadioButton controls by dragging it to the form in the design view. If you're using
Visual Studio 2019 or later, a red line helps you center the control.
2. In the XAML view, change the value of Content for the Button control
from Content="Button" to Content="Display", and then save the changes.
Your window should resemble the following illustration.
The XAML markup should now look similar to the following example:
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="252,47,0,0" TextWrapping="Wrap" Text="Select a message
option and then choose the Display button." VerticalAlignment="Top"/>
<RadioButton
x:Name="HelloButton"
Content="Hello"
Margin="297,161,0,0" VerticalAlignment="Top"/>
105
IsChecked="True"
HorizontalAlignment="Left"
<RadioButton x:Name="GoodbyeButton" Content="Goodbye" HorizontalAlignment="Left" Margin="488,161,0,0"
VerticalAlignment="Top"/>
<Button
Content="Display"
HorizontalAlignment="Left"
Margin="377,270,0,0"
VerticalAlignment="Top"
Width="75"/>
</Grid>
Add code to the display button
When this application runs, a message box appears after a user chooses a radio button and then
chooses the Display button. One message box will appear for Hello, and another will appear for
Goodbye. To create this behavior, you'll add code to the Button_Click event in Greetings.xaml.cs.
1. On the design surface, double-click the Display button.
Greetings.xaml.cs opens, with the cursor in the Button_Click event.
private void Button_Click(object sender, RoutedEventArgs e)
{
}
2. Enter the following code:
if (HelloButton.IsChecked == true)
{
MessageBox.Show("Hello.");
}
else if (GoodbyeButton.IsChecked == true)
{
MessageBox.Show("Goodbye.");
}
3. Save the application.
Debug and test the application
Find and fix errors
In this step, you'll find the error that we caused earlier by changing the name of
the MainWindow.xaml file.
Start debugging and find the error
1. Start the debugger by pressing F5 or selecting Debug, then Start Debugging.
A Break Mode window appears, and the Output window indicates that an
IOException has occurred: Cannot locate resource 'mainwindow.xaml'.
106
2. Stop the debugger by choosing Debug > Stop Debugging.
We renamed MainWindow.xaml to Greetings.xaml at the start of this tutorial, but the code still
refers to MainWindow.xaml as the startup URI for the application, so the project can't start.
Specify Greetings.xaml as the startup URI
1. In Solution Explorer, open the App.xaml file.
2. Change StartupUri="MainWindow.xaml" to StartupUri="Greetings.xaml", and then
save the changes.
Start the debugger again (press F5). You should see the Greetings window of the application.
Now close the application window to stop debugging.
What is XAML?
XAML, which stands for eXtensible Application Markup Language, is Microsoft's variant of XML
for describing a GUI. In previous GUI frameworks, like WinForms, a GUI was created in the same
language that you would use for interacting with the GUI, e.g. C# or VB.NET and usually
maintained by the designer (e.g. Visual Studio), but with XAML, Microsoft is going another way.
Much like with HTML, you are able to easily write and edit your GUI.
107
This is not really a XAML tutorial, but I will briefly tell you about how you use it, because it's such
an essential part of WPF. Whether you're creating a Window or a Page, it will consist of a XAML
document and a CodeBehind file, which together creates the Window/Page. The XAML file
describes the interface with all its elements, while the CodeBehind handles all the events and has
access to manipulate with the XAML controls.
Basic XAML
Creating a control in XAML is as easy as writing its name, surrounded by angle brackets. For
instance, a Button looks like this:
<Button>
XAML tags has to be ended, either by writing the end tag or by putting a forward slash at the
end of the start tag:
<Button></Button>
Or
<Button />
A lot of controls allow you to put content between the start and end tags, which is then the
content of the control. For instance, the Button control allows you to specify the text shown on it
between the start and end tags:
<Button>A button</Button>
HTML is not case-sensitive, but XAML is, because the control name has to correspond to a type
in the .NET framework. The same goes for attribute names, which corresponds to the properties
of the control. Here's a button where we define a couple of properties by adding attributes to the
tag:
<Button FontWeight="Bold" Content="A button" />
We set the FontWeight property, giving us bold text, and then we set the Content property, which
is the same as writing the text between the start and end tag. However, all attributes of a control
may also be defined like this, where they appear as child tags of the main control, using the
Control-Dot-Property notation:
<Button>
<Button.FontWeight>Bold</Button.FontWeight>
<Button.Content>A button</Button.Content>
</Button>
The result is exactly the same as above, so in this case, it's all about syntax and nothing else.
However, a lot of controls allow content other than text, for instance other controls. Here's an
108
example where we have text in different colors on the same button by using several TextBlock
controls inside of the Button:
<Button>
<Button.FontWeight>Bold</Button.FontWeight>
<Button.Content>
<WrapPanel>
<TextBlock Foreground="Blue">Multi</TextBlock>
<TextBlock Foreground="Red">Color</TextBlock>
<TextBlock>Button</TextBlock>
</WrapPanel>
</Button.Content>
</Button>
The Content property only allows for a single child element, so we use a WrapPanel to contain
the differently colored blocks of text. Panels, like the WrapPanel, plays an important role in WPF
and we will discuss them in much more details later on - for now, just consider them as containers
for other controls.
The exact same result can be accomplished with the following markup, which is simply another
way of writing the same:
<Button FontWeight="Bold">
<WrapPanel>
<TextBlock Foreground="Blue">Multi</TextBlock>
<TextBlock Foreground="Red">Color</TextBlock>
<TextBlock>Button</TextBlock>
</WrapPanel>
</Button>
Events in XAML
Most modern UI frameworks are event driven and so is WPF. All of the controls, including the
Window (which also inherits the Control class) exposes a range of events that you may subscribe
to. You can subscribe to these events, which means that your application will be notified when
they occur and you may react to that.
There are many types of events, but some of the most commonly used are there to respond to
the user's interaction with your application using the mouse or the keyboard. On most controls
you will find events like KeyDown, KeyUp, MouseDown, MouseEnter, MouseLeave, MouseUp
and several others.
We will look more closely at how events work in WPF, since this is a complex topic, but for now,
you need to know how to link a control event in XAML to a piece of code in your Code-behind file.
Have a look at this example:
<Window x:Class="WpfTutorialSamples.XAML.EventsSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
109
Title="EventsSample" Height="300" Width="300">
<Grid Name="pnlMainGrid" MouseUp="pnlMainGrid_MouseUp"
Background="LightBlue">
</Grid>
</Window>
Notice how we have subscribed to the MouseUp event of the Grid by writing a method name. This
method needs to be defined in code-behind, using the correct event signature. In this case it
should look like this:
private void pnlMainGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("You clicked me at " + e.GetPosition(this).ToString());
}
The MouseUp event uses a delegate called MouseButtonEventHandler, which you subscribe
to. It has two parameters, a sender (the control which raised the event) and a
MouseButtonEventArgs object that will contain useful information. We use it in the example to get
the position of the mouse cursor and tell the user about it.
Several events may use the same delegate type - for instance, both MouseUp and MouseDown
uses the MouseButtonEventHandler delegate, while the MouseMove event uses
the MouseEventHandler delegate. When defining the event handler method, you need to know
which delegate it uses and if you don't know that, you can look it up in the documentation.
Fortunately, Visual Studio can help us to generate a correct event handler for an event. The
easiest way to do this is to simply write the name of the event in XAML and then let the IntelliSense
of VS do the rest for you:
When you select <New Event Handler> Visual Studio will generate an appropriate event handler
in your Code-behind file. It will be named <control name>_<event name>, in our
case pnlMainGrid_MouseDown. Right-click in the event name and select Navigate to Event
Handler and VS will take you right to it.
110
Subscribing to an event from Code-behind
The most common way to subscribe to events is explained above, but there may be times where
you want to subscribe to the event directly from Code-behind instead. This is done using the +=
C# syntax, where you add an event handler to event directly on the object. The full explanation of
this belongs in a dedicated C# example, but for comparison, here's an example:
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfTutorialSamples.XAML
{
public partial class EventsSample : Window
{
public EventsSample()
{
InitializeComponent();
pnlMainGrid.MouseUp += new
MouseButtonEventHandler(pnlMainGrid_MouseUp);
}
private void pnlMainGrid_MouseUp(object sender, MouseButtonEventArgs
e)
{
MessageBox.Show("You clicked me at " +
e.GetPosition(this).ToString());
}
}
}
Once again, you need to know which delegate to use, and once again, Visual Studio can help you
with this. As soon as you write:
pnlMainGrid.MouseDown +=
Visual Studio will offer its assistance:
Simply press the [Tab] key twice to have Visual Studio generate the correct event handler for you,
right below the current method, ready for implementation. When you subscribe to the events like
this, you don't need to do it in XAML.
111
Basic Controls
The TextBlock control
TextBlock is not a control, per se, since it doesn't inherit from the Control class, but it's used much
like any other control in the WPF framework, so we'll call it a control to keep things simple.
The TextBlock control is one of the most fundamental controls in WPF, yet it's very useful. It
allows you to put text on the screen, much like a Label control does, but in a simpler and less
resource demanding way. A common understanding is that a Label is for short, one-line texts (but
may include e.g. an image), while the TextBlock works very well for multiline strings as well, but
can only contain text (strings). Both the Label and the TextBlock offers their own unique
advantages, so what you should use very much depends on the situation.
We already used a TextBlock control in the "Hello, WPF!" article, but for now, let's have a look at
the TextBlock in its simplest form:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockSample" Height="100" Width="200">
<Grid>
<TextBlock>This is a TextBlock</TextBlock>
</Grid>
</Window>
That's as simple as it comes and if you have read the previous chapters of this tutorial, then there
should be nothing new here. The text between the TextBlock is simply a shortcut for setting the
Text property of the TextBlock.
For the next example, let's try a longer text to show how the TextBlock deals with that. I've also
added a bit of margin, to make it look just a bit better:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockSample" Height="100" Width="200">
<Grid>
<TextBlock Margin="10">This is a TextBlock control and it comes with
a very long text</TextBlock>
</Grid>
</Window>
112
Dealing with long strings
As you will soon realize from the screenshot, the TextBlock is perfectly capable of dealing with
long, multiline texts, but it will not do anything by default. In this case the text is too long to be
rendered inside the window, so WPF renders as much of the text as possible and then just stops.
Fortunately, there are several ways of dealing with this. In the next example I'll show you all of
them, and then I'll explain each of them afterwards:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockSample" Height="200" Width="250">
<StackPanel>
<TextBlock Margin="10" Foreground="Red">
This is a TextBlock control<LineBreak />
with multiple lines of text.
</TextBlock>
<TextBlock Margin="10" TextTrimming="CharacterEllipsis"
Foreground="Green">
This is a TextBlock control with text that may not be
rendered completely, which will be indicated with an ellipsis.
</TextBlock>
<TextBlock Margin="10" TextWrapping="Wrap" Foreground="Blue">
This is a TextBlock control with automatically wrapped text,
using the TextWrapping property.
</TextBlock>
</StackPanel>
</Window>
113
So, we have three TextBlock controls, each with a different color (using the Foreground property)
for an easier overview. They all handle the fact that their text content is too long in different ways:
The red TextBlock uses a LineBreak tag to manually break the line at a designated location. This
gives you absolute control over where you want the text to break onto a new line, but it's not very
flexible for most situations. If the user makes the window bigger, the text will still wrap at the same
position, even though there may now be room enough to fit the entire text onto one line.
The green TextBlock uses the TextTrimming property with the value CharacterEllipsis to make
the TextBlock show an ellipsis (...) when it can't fit any more text into the control. This is a common
way of showing that there's more text, but not enough room to show it. This is great when you
have text that might be too long but you absolutely don't want it to use more than one line. As an
alternative to CharacterEllipsis you may use WordEllipsis, which will trim the text at the end of
the last possible word instead of the last possible character, preventing that a word is only shown
in part.
The blue TextBlock uses the TextWrapping property with the value Wrap, to make the TextBlock
wrap to the next line whenever it can't fit anymore text into the previous line. Contrary to the first
TextBlock, where we manually define where to wrap the text, this happens completely automatic
and even better: It's also automatically adjusted as soon as the TextBlock get more or less space
available. Try making the window in the example bigger or smaller and you will see how the
wrapping is updated to match the situation.
This was all about dealing with simple strings in the TextBlock. In the next chapter, we'll look into
some of the more advanced functionality of the TextBlock, which allows us to create text of various
styles within the TextBlock and much more.
The Label control
The Label control, in its most simple form, will look very much like the TextBlock which we used
in another article. You will quickly notice though that instead of a Text property, the Label has a
Content property. The reason for that is that the Label can host any kind of control directly inside
of it, instead of just text. This content can be a string as well though, as you will see in this first
and very basic example:
<Window x:Class="WpfTutorialSamples.Basic_controls.LabelControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LabelControlSample" Height="100" Width="200">
<Grid>
<Label Content="This is a Label control." />
</Grid>
</Window>
114
Another thing you might notice is the fact that the Label, by default, has a bit of padding, allowing
the text to be rendered a few pixels away from the top, left corner. This is not the case for the
TextBlock control, where you will have to specify it manually.
In a simple case like this, where the content is simply a string, the Label will actually create a
TextBlock internally and show your string in that.
The Label control vs. the TextBlock control
So why use a Label at all then? Well, there are a few important differences between the Label
and the TextBlock. The TextBlock only allows you to render a text string, while the Label also
allows you to:
▪
▪
▪
▪
Specify a border
Render other controls, e.g. an image
Use templated content through the ContentTemplate property
Use access keys to give focus to related controls
The last bullet point is actually one of the main reasons for using a Label over the TextBlock
control. Whenever you just want to render simple text, you should use the TextBlock control, since
it's lighter and performs better than the Label in most cases.
Label and Access keys (mnemonics)
In Windows and other operating systems as well, it's common practice that you can access
controls in a dialog by holding down the [Alt] key and then pressing a character which corresponds
to the control that you wish to access. The character to press will be highlighted when you hold
down the [Alt] key. TextBlock controls doesn't support this functionality, but the Label does, so for
control labels, the Label control is usually an excellent choice. Let's look at an example of it in
action:
<Window x:Class="WpfTutorialSamples.Basic_controls.LabelControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LabelControlSample" Height="180" Width="250">
<StackPanel Margin="10">
<Label Content="_Name:" Target="{Binding ElementName=txtName}" />
<TextBox Name="txtName" />
<Label Content="_Mail:" Target="{Binding ElementName=txtMail}" />
<TextBox Name="txtMail" />
</StackPanel>
</Window>
115
The screenshot shows our sample dialog as it looks when the Alt key is pressed. Try running it,
holding down the [Alt] key and then pressing N and M. You will see how focus is moved between
the two textboxes.
So, there's several new concepts here. First of all, we define the access key by placing an
underscore (_) before the character. It doesn't have to be the first character, it can be before any
of the characters in your label content. The common practice is to use the first character that's
not already used as an access key for another control.
We use the Target property to connect the Label and the designated control. We use a standard
WPF binding for this, using the ElementName property, all of which we will describe later on in
this tutorial. The binding is based on the name of the control, so if you change this name, you will
also have to remember to change the binding.
Using controls as Label content
As already mentioned, the Label control allows you to host other controls, while still keeping the
other benefits. Let's try an example where we have both an image and a piece of text inside the
Label, while also having an access key for each of the labels:
<Window x:Class="WpfTutorialSamples.Basic_controls.LabelControlAdvancedSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LabelControlAdvancedSample" Height="180" Width="250">
<StackPanel Margin="10">
<Label Target="{Binding ElementName=txtName}">
<StackPanel Orientation="Horizontal">
<Image
Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_green.png" />
<AccessText Text="_Name:" />
</StackPanel>
</Label>
<TextBox Name="txtName" />
<Label Target="{Binding ElementName=txtMail}">
<StackPanel Orientation="Horizontal">
<Image
Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_blue.png" />
<AccessText Text="_Mail:" />
</StackPanel>
</Label>
116
<TextBox Name="txtMail" />
</StackPanel>
</Window>
This is just an extended version of the previous example - instead of a simple text string, our Label
will now host both an image and a piece of text (inside the AccessText control, which allows us
to still use an access key for the label). Both controls are inside a horizontal StackPanel, since
the Label, just like any other ContentControl derivate, can only host one direct child control.
The TextBox control
The TextBox control is the most basic text-input control found in WPF, allowing the end-user to
write plain text, either on a single line, for dialog input, or in multiple lines, like an editor.
Single-line TextBox
The TextBox control is such a commonly used thing that you actually don't have to use any
properties on it, to have a full-blown editable text field. Here's a barebone example:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBoxSample" Height="80" Width="250">
<StackPanel Margin="10">
<TextBox />
</StackPanel>
</Window>
117
That's all you need to get a text field. I added the text after running the sample and before taking
the screenshot, but you can do it through markup as well, to pre-fill the textbox, using the Text
property:
<TextBox Text="Hello, world!" />
Try right-clicking in the TextBox. You will get a menu of options, allowing you to use the TextBox
with the Windows Clipboard. The default keyboard shortcuts for undoing and redoing (Ctrl+Z and
Ctrl+Y) should also work, and all of this functionality you get for free!
Multi-line TextBox
If you run the above example, you will notice that the TextBox control by default is a single-line
control. Nothing happens when you press Enter and if you add more text than what can fit on a
single line, the control just scrolls. However, making the TextBox control into a multi-line editor is
very simple:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBoxSample" Height="160" Width="280">
<Grid Margin="10">
<TextBox AcceptsReturn="True" TextWrapping="Wrap" />
</Grid>
</Window>
I have added two properties: The AcceptsReturn makes the TextBox into a multi-line control by
allowing the use of the Enter/Return key to go to the next line, and the TextWrapping property,
which will make the text wrap automatically when the end of a line is reached.
Spellcheck with TextBox
As an added bonus, the TextBox control actually comes with automatic spell checking for English
and a couple of other languages (as of writing, English, French, German, and Spanish languages
are supported).
It works much like in Microsoft Word, where spelling errors are underlined and you can right-click
it for suggested alternatives. Enabling spell checking is very easy:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
118
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBoxSample" Height="160" Width="280">
<Grid Margin="10">
<TextBox AcceptsReturn="True" TextWrapping="Wrap"
SpellCheck.IsEnabled="True" Language="en-US" />
</Grid>
</Window>
We have used the previous, multi-line textbox example as the basis and then I have added two
new properties: The attached property from the SpellCheck class called IsEnabled, which simply
enables spell checking on the parent control, and the Language property, which instructs the spell
checker which language to use.
Working with TextBox selections
Just like any other editable control in Windows, the TextBox allows for selection of text, e.g. to
delete an entire word at once or to copy a piece of the text to the clipboard. The WPF TextBox
has several properties for working with selected text, all of them which you can read or even
modify. In the next example, we will be reading these properties:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBoxSelectionSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBoxSelectionSample" Height="150" Width="300">
<DockPanel Margin="10">
<TextBox SelectionChanged="TextBox_SelectionChanged"
DockPanel.Dock="Top" />
<TextBox Name="txtStatus" AcceptsReturn="True" TextWrapping="Wrap"
IsReadOnly="True" />
</DockPanel>
</Window>
The example consists of two TextBox controls: One for editing and one for outputting the current
selection status to. For this, we set the IsReadOnly property to true, to prevent editing of the status
TextBox. We subscribe the SelectionChanged event on the first TextBox, which we handle in the
Code-behind:
using System;
using System.Text;
119
using System.Windows;
using System.Windows.Controls;
namespace WpfTutorialSamples.Basic_controls
{
public partial class TextBoxSelectionSample : Window
{
public TextBoxSelectionSample()
{
InitializeComponent();
}
private void TextBox_SelectionChanged(object sender, RoutedEventArgs
e)
{
TextBox textBox = sender as TextBox;
txtStatus.Text = "Selection starts at character #" +
textBox.SelectionStart + Environment.NewLine;
txtStatus.Text += "Selection is " + textBox.SelectionLength
+ " character(s) long" + Environment.NewLine;
txtStatus.Text += "Selected text: '" + textBox.SelectedText
+ "'";
}
}
}
We use three interesting properties to accomplish this:
SelectionStart , which gives us the current cursor position or if there's a selection: Where it starts.
SelectionLength , which gives us the length of the current selection, if any. Otherwise it will just
return 0.
SelectedText , which gives us the currently selected string if there's a selection. Otherwise an
empty string is returned.
Modifying the selection
All of these properties are both readable and writable, which means that you can modify them as
well. For instance, you can set the SelectionStart and SelectionLength properties to select a
custom range of text, or you can use the SelectedText property to insert and select a string. Just
120
remember that the TextBox has to have focus, e.g. by calling the Focus() method first, for this to
work.
The Button control
No GUI framework would be complete without a Button control, so of course WPF has a nice one
included, and just like the rest of the framework controls, it's very flexible and will allow you to
accomplish almost anything. But let's start out with some basic examples.
A Simple Button
Just like many other WPF controls, a Button can be displayed simply by adding a Button tag to
your Window. If you put text between the tags (or another control), it will act as the content of the
Button:
<Button>Hello, world!</Button>
Pretty simple, right? Of course, the Button doesn't actually do anything yet, but if you point to it,
you will find that it comes with a nice hover effect right out of the box. But let's make the Button
do something, by subscribing to its Click event (more information about this process can be found
in the article on subscribing to events in XAML):
<Button Click="HelloWorldButton_Click">Hello, World!</Button>
In Code-behind, you will need a matching method to handle the click:
private void HelloWorldButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello, world!");
}
You now have a very basic button and when you click on it, a message will be displayed!
121
Formatted content
Internally, simple text inside the Content of the Button is turned into a TextBlock control, which
also means that you can control the same aspects of the text formatting. You will find several
properties on the Button control for doing this, including (but not limited
to) Foreground, Background, FontWeight and so on. In other words, it's very easy to change
the formatting of the text inside a Button control:
<Button Background="Beige" Foreground="Blue" FontWeight="Bold">Formatted
Button</Button>
By setting these properties directly on the Button, you are of course limited to applying the same
formatting for all of the content, but if that's not good enough, just read on for even more advanced
content formatting.
Buttons with Advanced Content
We have already talked about this several times, but one of the very cool things about WPF is the
ability to replace simple text inside a control with other WPF controls. This also means that you
don't have to limit your buttons to simple text, formatted in the same way - you can just add several
text controls with different formatting. The WPF Button only supports one direct child control, but
you can just make that a Panel, which will then host as many controls as you need to. You can
use this to create buttons with various types of formatting:
<Button>
<StackPanel Orientation="Horizontal">
<TextBlock>Formatted </TextBlock>
<TextBlock Foreground="Blue" FontWeight="Bold" Margin="2,0">Button</TextBlock>
<TextBlock Foreground="Gray" FontStyle="Italic">[Various]</TextBlock>
</StackPanel>
</Button>
But of course, you are not limited to just text - you can put whatever you want inside your buttons,
which leads us to a subject that I know many people will ask for. Buttons with images!
122
Buttons with Images (ImageButton)
In many UI frameworks, you will find a regular Button and then one or several other variants,
which will offer extra features. One of the most commonly used variants is the ImageButton,
which, as the name implies, is a Button which will usually allow you to include an image before
the text. But in WPF, there's no need for a separate control to accomplish this - as you just saw,
we can put several controls inside a Button, so you can just as easily add an Image control to it,
like this:
<Button Padding="5">
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/help.png" />
<TextBlock Margin="5,0">Help</TextBlock>
</StackPanel>
</Button>
It's really that simple to create an ImageButton in WPF, and you are of course free to move things
around, e.g. if you want the image after the text instead of before etc.
Button Padding
You may have noticed that buttons in the WPF framework doesn't come with any padding by
default. This means that the text is very close to the borders, which might look a little bit strange,
because most buttons found elsewhere (web, other applications etc.) do have at least some
padding in the sides. No worries, because the Button comes with a Padding property:
<Button Padding="5,2">Hello, World!</Button>
This will apply a padding of 5 pixels on the sides, and 2 pixels in the top and bottom. But having
to apply padding to all of your buttons might get a bit tiresome at a certain point, so here's a small
tip: You can apply the padding globally, either across the entire application or just this specific
Window, using a Style (more on styles later). Here's an example where we apply it to the Window,
using the Window.Resources property:
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Padding" Value="5,2"/>
</Style>
</Window.Resources>
123
This padding will now be applied to all your buttons, but you can of course override it by
specifically defining the Padding property on a Button. Here's how all the buttons of this example
look with the common padding:
The CheckBox control
The CheckBox control allows the end-user to toggle an option on or off, usually reflecting a
Boolean value in the Code-behind. Let's jump straight into an example, in case you're not sure
how a CheckBox looks:
<Window x:Class="WpfTutorialSamples.Basic_controls.CheckBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxSample" Height="140" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<CheckBox>Enable feature ABC</CheckBox>
<CheckBox IsChecked="True">Enable feature XYZ</CheckBox>
<CheckBox>Enable feature WWW</CheckBox>
</StackPanel>
</Window>
As you can see, the CheckBox is very easy to use. On the second CheckBox, I use the IsChecked
property to have it checked by default, but other than that, no properties are needed to use it. The
IsChecked property should also be used from Code-behind if you want to check whether a certain
CheckBox is checked or not.
124
Custom content
The CheckBox control inherits from the ContentControl class, which means that it can take
custom content and display next to it. If you just specify a piece of text, like I did in the example
above, WPF will put it inside a TextBlock control and display it, but this is just a shortcut to make
things easier for you. You can use any type of control inside of it, as we'll see in the next example:
<Window x:Class="WpfTutorialSamples.Basic_controls.CheckBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxSample" Height="140" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<CheckBox>
<TextBlock>
Enable feature <Run Foreground="Green"
FontWeight="Bold">ABC</Run>
</TextBlock>
</CheckBox>
<CheckBox IsChecked="True">
<WrapPanel>
<TextBlock>
Enable feature <Run
FontWeight="Bold">XYZ</Run>
</TextBlock>
<Image
Source="/WpfTutorialSamples;component/Images/question.png" Width="16" Height="16"
Margin="5,0" />
</WrapPanel>
</CheckBox>
<CheckBox>
<TextBlock>
Enable feature <Run Foreground="Blue"
TextDecorations="Underline" FontWeight="Bold">WWW</Run>
</TextBlock>
</CheckBox>
</StackPanel>
</Window>
As you can see from the sample markup, you can do pretty much whatever you want with the
content. On all three check boxes, I do something differently with the text, and on the middle one
I even throw in an Image control. By specifying a control as the content, instead of just text, we
125
get much more control of the appearance, and the cool thing is that no matter which part of the
content you click on, it will activate the CheckBox and toggle it on or off.
The IsThreeState property
As mentioned, the CheckBox usually corresponds to a boolean value, which means that it only
has two states: true or false (on or off). However, since a boolean data type might be nullable,
effectively allowing for a third option (true, false or null), the CheckBox control can also support
this case. By setting the IsThreeState property to true, the CheckBox will get a third state called
"the indeterminate state".
A common usage for this is to have a "Enable all" CheckBox, which can control a set of child
checkboxes, as well as show their collective state. Our example shows how you may create a list
of features that can be toggled on and off, with a common "Enable all" CheckBox in the top:
XAML:
<Window x:Class="WpfTutorialSamples.Basic_controls.CheckBoxThreeStateSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxThreeStateSample" Height="170" Width="300">
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<StackPanel Margin="10,5">
<CheckBox IsThreeState="True" Name="cbAllFeatures"
Checked="cbAllFeatures_CheckedChanged"
Unchecked="cbAllFeatures_CheckedChanged">Enable all</CheckBox>
<StackPanel Margin="20,5">
<CheckBox Name="cbFeatureAbc"
Checked="cbFeature_CheckedChanged" Unchecked="cbFeature_CheckedChanged">Enable
feature ABC</CheckBox>
<CheckBox Name="cbFeatureXyz" IsChecked="True"
Checked="cbFeature_CheckedChanged" Unchecked="cbFeature_CheckedChanged">Enable
feature XYZ</CheckBox>
<CheckBox Name="cbFeatureWww"
Checked="cbFeature_CheckedChanged" Unchecked="cbFeature_CheckedChanged">Enable
feature WWW</CheckBox>
</StackPanel>
</StackPanel>
</StackPanel>
</Window>
C#:
using System;
using System.Windows;
namespace WpfTutorialSamples.Basic_controls
{
public partial class CheckBoxThreeStateSample : Window
{
public CheckBoxThreeStateSample()
126
{
InitializeComponent();
}
private void cbAllFeatures_CheckedChanged(object sender,
RoutedEventArgs e)
{
bool newVal = (cbAllFeatures.IsChecked == true);
cbFeatureAbc.IsChecked = newVal;
cbFeatureXyz.IsChecked = newVal;
cbFeatureWww.IsChecked = newVal;
}
private void cbFeature_CheckedChanged(object sender, RoutedEventArgs
e)
{
cbAllFeatures.IsChecked = null;
if((cbFeatureAbc.IsChecked == true) &&
(cbFeatureXyz.IsChecked == true) && (cbFeatureWww.IsChecked == true))
cbAllFeatures.IsChecked = true;
if((cbFeatureAbc.IsChecked == false) &&
(cbFeatureXyz.IsChecked == false) && (cbFeatureWww.IsChecked == false))
cbAllFeatures.IsChecked = false;
}
}
}
This example works from two different angles: If you check or uncheck the "Enable all" CheckBox,
then all of the child check boxes, each representing an application feature in our example, is either
checked or unchecked. It also works the other way around though, where checking or unchecking
a child CheckBox affects the "Enable all" CheckBox state: If they are all checked or unchecked,
127
then the "Enable all" CheckBox gets the same state - otherwise the value will be left with a null,
which forces the CheckBox into the indeterminate state.
All of this behavior can be seen on the screenshots above, and is achieved by subscribing to the
Checked and Unchecked events of the CheckBox controls. In a real world example, you would
likely bind the values instead, but this example shows the basics of using the IsThreeState
property to create a "Toggle all" effect.
The RadioButton control
The RadioButton control allows you to give your user a list of possible options, with only one of
them selected at the same time. You can achieve the same effect, using less space, with the
ComboBox control, but a set of radio buttons tend to give the user a better overview of the options
they have.
<Window x:Class="WpfTutorialSamples.Basic_controls.RadioButtonSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="RadioButtonSample" Height="150" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Are you ready?</Label>
<RadioButton>Yes</RadioButton>
<RadioButton>No</RadioButton>
<RadioButton IsChecked="True">Maybe</RadioButton>
</StackPanel>
</Window>
All we do is add a Label with a question, and then three radio buttons, each with a possible
answer. We define a default option by using the IsChecked property on the last RadioButton,
which the user can change simply by clicking on one of the other radio buttons. This is also the
property you would want to use from Code-behind to check if a RadioButton is checked or
not.
128
RadioButton groups
If you try running the example above, you will see that, as promised, only one RadioButton can
be checked at the same time. But what if you want several groups of radio buttons, each with their
own, individual selection? This is what the GroupName property comes into play, which allows
you to specify which radio buttons belong together. Here's an example:
<Window x:Class="WpfTutorialSamples.Basic_controls.RadioButtonSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="RadioButtonSample" Height="230" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Are you ready?</Label>
<RadioButton GroupName="ready">Yes</RadioButton>
<RadioButton GroupName="ready">No</RadioButton>
<RadioButton GroupName="ready" IsChecked="True">Maybe</RadioButton>
<Label FontWeight="Bold">Male or female?</Label>
<RadioButton GroupName="sex">Male</RadioButton>
<RadioButton GroupName="sex">Female</RadioButton>
<RadioButton GroupName="sex" IsChecked="True">Not sure</RadioButton>
</StackPanel>
</Window>
With the GroupName property set on each of the radio buttons, a selection can now be made for
each of the two groups. Without this, only one selection for all six radio buttons would be possible.
Custom content
The RadioButton inherits from the ContentControl class, which means that it can take custom
content and display next to it. If you just specify a piece of text, like I did in the example above,
WPF will put it inside a TextBlock control and display it, but this is just a shortcut to make things
easier for you. You can use any type of control inside of it, as we'll see in the next example:
<Window x:Class="WpfTutorialSamples.Basic_controls.RadioButtonCustomContentSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
129
Title="RadioButtonCustomContentSample" Height="150" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Are you ready?</Label>
<RadioButton>
<WrapPanel>
<Image
Source="/WpfTutorialSamples;component/Images/accept.png" Width="16" Height="16"
Margin="0,0,5,0" />
<TextBlock Text="Yes" Foreground="Green" />
</WrapPanel>
</RadioButton>
<RadioButton Margin="0,5">
<WrapPanel>
<Image
Source="/WpfTutorialSamples;component/Images/cancel.png" Width="16" Height="16"
Margin="0,0,5,0" />
<TextBlock Text="No" Foreground="Red" />
</WrapPanel>
</RadioButton>
<RadioButton IsChecked="True">
<WrapPanel>
<Image
Source="/WpfTutorialSamples;component/Images/question.png" Width="16" Height="16"
Margin="0,0,5,0" />
<TextBlock Text="Maybe" Foreground="Gray" />
</WrapPanel>
</RadioButton>
</StackPanel>
</Window>
Markup-wise, this example gets a bit heavy, but the concept is pretty simple. For each
RadioButton, we have a WrapPanel with an image and a piece of text inside of it. Since we now
take control of the text using a TextBlock control, this also allows us to format the text in any way
we want to. For this example, I have changed the text color to match the choice. An Image control
(read more about those later) is used to display an image for each choice.
Notice how you can click anywhere on the RadioButton, even on the image or the text, to toggle
it on, because we have specified it as content of the RadioButton. If you had placed it as a
separate panel, next to the RadioButton, the user would have to click directly on the round circle
of the RadioButton to activate it, which is less practical.
130
The PasswordBox control
For editing regular text in WPF we have the TextBox, but what about editing passwords? The
functionality is very much the same, but we want WPF to display something else than the actual
characters when typing in a password, to shield it from nosy people looking over your shoulder.
For this purpose, WPF has the PasswordBox control, which is just as easy to use as the
TextBox. Allow me to illustrate with an example:
<Window x:Class="WpfTutorialSamples.Basic_controls.PasswordBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PasswordBoxSample" Height="160" Width="300">
<StackPanel Margin="10">
<Label>Text:</Label>
<TextBox />
<Label>Password:</Label>
<PasswordBox />
</StackPanel>
</Window>
In the screenshot, I have entered the exact same text into the two text boxes, but in the password
version, the characters are replaced with dots. You can actually control which character is used
instead of the real characters, using the PasswordChar property:
<PasswordBox PasswordChar="X" />
In this case, the character X will be used instead of the dots. In case you need to control the
length of the password, there's a MaxLength property for you:
<PasswordBox MaxLength="6" />
I have used both properties in this updated example:
<Window x:Class="WpfTutorialSamples.Basic_controls.PasswordBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PasswordBoxSample" Height="160" Width="300">
<StackPanel Margin="10">
<Label>Text:</Label>
<TextBox />
131
<Label>Password:</Label>
<PasswordBox MaxLength="6" PasswordChar="X" />
</StackPanel>
</Window>
Notice how the characters are now X's instead, and that I was only allowed to enter 6 characters
in the box.
132
Course Materials:
https://wpf-tutorial.com/
https://www.tutorialspoint.com/wpf/index.htm
https://docs.microsoft.com/en-us/visualstudio/get-started/csharp/tutorial-wpf?view=vs-2019
Assessment and Activities:
Create a form allowing you to add, subtract, divide and
multiply numbers:
Having created your window, first attach code to the
buttons so that if you leave one of the numbers blank (or
enter an invalid number) you get an error message:
If, on the other hand, you enter valid numbers, you should see the
answer appear in a label at the bottom of the window (set its
Visibility property in XAML to Collapsed, then set it to
Visiibility.Visible in code):
133
Module 5
ADO.Net and Exception Handling
Overview:
ADO.NET is a set of classes that allows you to connect and work with data sources
like databases, excel file, access file, xml file, mysql, sql or notepad. To connect your
application with different sources of database you need to know the right Data Provider. There
are several Data Providers in ADO.NET that connects with different types of sources.
Module Objectives:
After successful Completion of this module, you should be able to:
•
•
•
Know how to use the basic ADO.Net insert values into them, query the tables,
retrieve the results of the queries, and update the tables.
Learn how to use simple statements and prepared statements, and you will see
an example of a stored procedure.
Learn how to perform transactions and how to catch exceptions and warnings.
134
What is ADO.Net?
ADO.NET provides a bridge between the front end controls and the back end database. The
ADO.NET objects encapsulate all the data access operations and the controls interact with these
objects to display data, thus hiding the details of movement of data.
The following figure shows the ADO.NET objects at a glance:
The DataSet Class
The dataset represents a subset of the database. It does not have a continuous connection to
the database. To update the database a reconnection is required. The DataSet contains
DataTable objects and DataRelation objects. The DataRelation objects represent the
relationship between two tables.
Following table shows some important properties of the DataSet class:
Properties
Description
CaseSensitive
Indicates whether string comparisons within the data tables
are case-sensitive.
Container
Gets the container for the component.
DataSetName
Gets or sets the name of the current data set.
DefaultViewManager
Returns a view of data in the data set.
DesignMode
Indicates whether the component is currently in design mode.
EnforceConstraints
Indicates whether constraint rules are followed when
attempting any update operation.
135
Events
Gets the list of event handlers that are attached to this
component.
ExtendedProperties
Gets the collection of customized user information associated
with the DataSet.
HasErrors
Indicates if there are any errors.
IsInitialized
Indicates whether the DataSet is initialized.
Locale
Gets or sets the locale information used to compare strings
within the table.
Namespace
Gets or sets the namespace of the DataSet.
Prefix
Gets or sets an XML prefix that aliases the namespace of the
DataSet.
Relations
Returns the collection of DataRelation objects.
Tables
Returns the collection of DataTable objects.
The following table shows some important methods of the DataSet class:
Methods
Description
AcceptChanges
Accepts all changes made since the DataSet was
loaded or this method was called.
BeginInit
Begins the initialization of the DataSet. The
initialization occurs at run time.
Clear
Clears data.
Clone
Copies the structure of the DataSet, including all
DataTable schemas, relations, and constraints.
Does not copy any data.
Copy
Copies both structure and data.
CreateDataReader()
Returns a DataTableReader with one result set
per DataTable, in the same sequence as the
tables appear in the Tables collection.
CreateDataReader(DataTable[])
Returns a DataTableReader with one result set
per DataTable.
EndInit
Ends the initialization of the data set.
136
Equals(Object)
Determines whether the specified Object is equal
to the current Object.
Finalize
Free resources and perform other cleanups.
GetChanges
Returns a copy of the DataSet with all changes
made since it was loaded or the AcceptChanges
method was called.
GetChanges(DataRowState)
Gets a copy of DataSet with all changes made
since it was loaded or the AcceptChanges
method was called, filtered by DataRowState.
GetDataSetSchema
Gets a copy of XmlSchemaSet for the DataSet.
GetObjectData
Populates a serialization information object with
the data needed to serialize the DataSet.
GetType
Gets the type of the current instance.
GetXML
Returns the XML representation of the data.
GetXMLSchema
Returns the XSD schema for the XML
representation of the data.
HasChanges()
Gets a value indicating whether the DataSet has
changes, including new, deleted, or modified
rows.
HasChanges(DataRowState)
Gets a value indicating whether the DataSet has
changes, including new, deleted, or modified
rows, filtered by DataRowState.
IsBinarySerialized
Inspects the format of the serialized
representation of the DataSet.
Load(IDataReader, LoadOption,
DataTable[])
Fills a DataSet with values from a data source
using the supplied IDataReader, using an array of
DataTable instances to supply the schema and
namespace information.
Load(IDataReader, LoadOption,
String[])
Fills a DataSet with values from a data source
using the supplied IDataReader, using an array of
strings to supply the names for the tables within
the DataSet.
Merge()
Merges the data with data from another DataSet.
This method has different overloaded forms.
137
ReadXML()
Reads an XML schema and data into the
DataSet. This method has different overloaded
forms.
ReadXMLSchema(0)
Reads an XML schema into the DataSet. This
method has different overloaded forms.
RejectChanges
Rolls back all changes made since the last call to
AcceptChanges.
WriteXML()
Writes an XML schema and data from the
DataSet. This method has different overloaded
forms.
WriteXMLSchema()
Writes the structure of the DataSet as an XML
schema. This method has different overloaded
forms.
The DataTable Class
The DataTable class represents the tables in the database. It has the following important
properties; most of these properties are read only properties except the PrimaryKey property:
Properties
Description
ChildRelations
Returns the collection of child relationship.
Columns
Returns the Columns collection.
Constraints
Returns the Constraints collection.
DataSet
Returns the parent DataSet.
DefaultView
Returns a view of the table.
ParentRelations
Returns the ParentRelations collection.
PrimaryKey
Gets or sets an array of columns as the primary key for the
table.
Rows
Returns the Rows collection.
138
The following table shows some important methods of the DataTable class:
Methods
Description
AcceptChanges
Commits all changes since the last AcceptChanges.
Clear
Clears all data from the table.
GetChanges
Returns a copy of the DataTable with all changes made since
the AcceptChanges method was called.
GetErrors
Returns an array of rows with errors.
ImportRows
Copies a new row into the table.
LoadDataRow
Finds and updates a specific row, or creates a new one, if not
found any.
Merge
Merges the table with another DataTable.
NewRow
Creates a new DataRow.
RejectChanges
Rolls back all changes made since the last call to
AcceptChanges.
Reset
Resets the table to its original state.
Select
Returns an array of DataRow objects.
The DataRow Class
The DataRow object represents a row in a table. It has the following important properties:
Properties
Description
HasErrors
Indicates if there are any errors.
Items
Gets or sets the data stored in a specific column.
ItemArrays
Gets or sets all the values for the row.
Table
Returns the parent table.
The following table shows some important methods of the DataRow class:
Methods
AcceptChanges
Description
Accepts all changes made since this method was called.
139
BeginEdit
Begins edit operation.
CancelEdit
Cancels edit operation.
Delete
Deletes the DataRow.
EndEdit
Ends the edit operation.
GetChildRows
Gets the child rows of this row.
GetParentRow
Gets the parent row.
GetParentRows
Gets parent rows of DataRow object.
RejectChanges
Rolls back all changes made since the last call to
AcceptChanges.
The DataAdapter Object
The DataAdapter object acts as a mediator between the DataSet object and the database. This
helps the Dataset to contain data from multiple databases or other data source.
The DataReader Object
The DataReader object is an alternative to the DataSet and DataAdapter combination. This
object provides a connection oriented access to the data records in the database. These objects
are suitable for read-only access, such as populating a list and then breaking the connection.
DbCommand and DbConnection Objects
The DbConnection object represents a connection to the data source. The connection could be
shared among different command objects.
The DbCommand object represents the command or a stored procedure sent to the database
from retrieving or manipulating data.
140
ADO.Net on C#
Connecting to a database
Connection to a database requires a connection string. This string has the information about the
server you're going to connect to, the database you will require, and the credentials that you can
use to connect. Each database has its own properties including the server name and type.
SqlConnection class represents a database connection. The following code creates a
SqlConnection object by passing a SQL Server connection string.
1. using(SqlConnection conn = new SqlConnection()) {
2.
conn.ConnectionString = "Server=[server_name];Database=[database_name];Trusted
_Connection=true";
3.
// using the code here...
4. }
In this connection string,
1. Server - Name of the server to connect to.
2. Database - This is the name of the database you're connecting to.
In all of the databases, there are two types of login methods. Windows Authentication and
Database Authentication. In Windows Authentication, the database is authenticated using the
user's credentials from Windows (the OS), and in Database Authentication you the username and
word, in order to connect to the database.
Connection pools
Connecting to a database, as already said, is a long process of opening the connection, closing
the connection, and so on. To repeat this process for every single user in the application is not a
good approach and will slow down the processes of code execution. So, in program executions,
many such connections would be opened and closed and again opened that are identical. These
processes are time-consuming and are the opposite of a good UX.
In the .NET Framework, ADO.NET plays a part in this and minimizes the opening and closing
process to make the program execution a bit faster by creating, what we call, a Connection Pool.
This technique reduces the number of times the connection is opened, by saving the instance of
the connection. For every new connection, it just looks for a connection already opened, and then
if the connection exists, doesn't attempt to create a new connection, otherwise, it opens a new
connection based on the connection string.
It must be remembered that only the connections with the same configuration can be pooled. Any
connection with even a single dissimilarity would require a new pool for itself. Generally, it is based
on the ConnectionString of the connection. You can learn how that would differ by changing the
values in the connection string.
141
An example from the MSDN documentation would be like:
1. using(SqlConnection connection = new SqlConnection(
2.
"Integrated Security=SSPI;Initial Catalog=Northwind")) {
3.
connection.Open();
4.
// Pool A is created.
5. }
6. using(SqlConnection connection = new SqlConnection(
7.
"Integrated Security=SSPI;Initial Catalog=pubs")) {
8.
connection.Open();
9.
// Pool B is created because the connection strings differ.
10. }
11. using(SqlConnection connection = new SqlConnection(
12. "Integrated Security=SSPI;Initial Catalog=Northwind")) {
13. connection.Open();
14. // The connection string matches pool A.
15. }
Why use "using" in code
In C# there are some objects that use the resources of the system. That needs to be removed,
closed, flushed and disposed of, and so on. In C# you can either write the code to create a new
instance to the resource, use it, close it, flush it and dispose of it. Or on the other hand, you can
simply just use this using statement block in which the object created is closed, flushed, and
disposed of and the resources are then allowed to be used again by other processes. This
ensures that the framework would take the best measures for each process.
We could have done it using the simple line to line code like:
1.
2.
3.
4.
5.
6.
7.
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "connection_string";
conn.Open();
// use the connection here
conn.Close();
conn.Dipose();
// remember, there is no method to flush a connection.
This was minimized as:
1. using(SqlConnection conn = new SqlConnection()) {
2.
conn.ConnectionString = "connection_string";
3.
conn.Open();
4. // use the connection here
5. }
142
Once the code would step out of this block. The resources would be closed and disposed of on
their own. The framework would take care of in the best way.
Executing the Commands
Once connected to the database, you can execute the set of commands that you're having and
which would execute on the server (or the data provider) to execute the function you're trying to
do, such as a query for data, insert the data, update records and so on and so forth.
SQL has the basic syntax for the commands and in my opinion, has the simple syntax of
commands and nearly human-understandable commands in the programming world. In the
namespace the class, SqlCommand does this job for us. An example of a command would be
like:
1. SqlCommand command = new SqlCommand("SELECT * FROM TableName", conn);
Each and every command on the SQL Server would be executed like this. The first parameter is
the command and the second one is the connection on which the command would execute. You
can any command into it and the underlying code would convert it back to the command that
would execute on the server where the data is present and then will return the result to you,
whether an error or a success report.
Sometimes you might want to use the command of the INSERT INTO clause. To work that out,
you will need to add parameters to the command, so that your database is safe from SQL
Injections. Using parameters would reduce the chances of your database being attacked, by
throwing an error if the user tries to add some commands (using the form) into the database
server.
Parameterizing the data
Parameterizing the query is done using the SqlParameter ed into the command. For example,
you might want to search for the records where the criteria match. You can denote that criteria,
by ing the variable name into the query and then adding the value to it using the SqlParameter
object. For instance, the following is your SqlCommand to be ed on to the server:
1. // Create the command
2. SqlCommand command = new SqlCommand("SELECT * FROM TableName WHERE Fi
rstColumn = @0", conn);
3. // Add the parameters.
4. command.Parameters.Add(new SqlParameter("0", 1));
In the preceding code, the variable added is 0 and the value to it is ed. You can use any variable
but it must start with a @ sign. Once that has been done, you can then add the parameters to that
name. In this case, the value 1 has been hardcoded and you can add a variable value here too.
143
Remember, the connection must be opened in order to run this code, you can use conn.Open()
to open the connection if asked.
As explained in the code, I have used the parameter as a number (0) that can also be a name.
For example, you can also write the code as:
1. // Create the command
2. SqlCommand command = new SqlCommand("SELECT * FROM TableName WHERE Fi
rstColumn = @firstColumnValue", conn);
3. // Add the parameters.
4. command.Parameters.Add(new SqlParameter("firstColumnValue", 1));
This way, it will be easier for you to keep them in mind. I am better at working with numbers and
indexes like in an array so I used 0, you can use a name, a combination of alphanumeric
characters, and so on. Just the name in the SqlParameter object and you'll be good to go!
Reading the data returned
In SQL you usually use the SELECT statement to get the data from the database to show,
CodeProject would do so to show the recent articles from their database, Google would do so to
index the results, and so on. But how to show those data results in the application using C#? That
is the question here. Well, in the namespace we're talking about, there is the class SqlDataReader
present for the SqlCommand that returns the Reader object for the data. You can use this to read
through the data and for each of the columns provide the results on the screen.
The following code would get the results from the command once executed:
1. // Create a new SqlDataReader object and read data from the command.
2. using(SqlDataReader reader = command.ExecuteReader()) {
3.
while there is another record present
4.
while (reader.Read()) {
5.
// write the data on to the screen
6.
Console.WriteLine(String.Format("{0} \t | {1} \t | {2} \t | {3}",
7.
// call the objects from their index
8.
reader[0], reader[1], reader[2], reader[3]));
9.
}
10. }
This is the same code, it will execute, and once done executing it will let the framework handle
the job and close the resources depending on the best method.
144
Adding data to the SQL Server
A similar method is implemented for adding the data to the database. Only the command would
change and we know in the database, the INSERT INTO clause is used to add the data. So, the
command would become:
1. SqlCommand insertCommand = new SqlCommand("INSERT INTO TableName (FirstCo
lumn, SecondColumn, ThirdColumn, ForthColumn) VALUES (@0, @1, @2, @3)", conn)
;
You can then use the SqlParameter objects to add the values to the parameters. This way, when
the command is executed the data would be added to the table that you've specified.
Catching the errors from SQL Server
SQL Server generates the errors for you to catch and work on them. In the namespace we're
working on there are two classes that work with the errors and exceptions thrown by SQL Server.
1. SqlError
2. SqlException
These are used to get the error details or to catch the exceptions in the code and print the data
results respectively. If you're going to use a try-catch block you're more likely to use the
SqlException thing in your code.
For this to work, we will a command that we know will throw an error.
1. SqlCommand errorCommand = new SqlCommand("SELECT * FROM someErrorColum
n", conn);
Now we know that this is faulty, but this won't generate any error, untill we execute it. To do so,
we will try to execute it like this:
1. errorCommand.ExecuteNonQuery();
Once this is executed, SQL Server would complain, saying there is no such table present. To
catch it you can simply use the try-catch block with the SqlException in the catch block to be
caught. For a working code, you can see the following code block in the live example of my article.
That explains the usage of the try-catch block with the SqlException here.
145
Working example
In the article, there is an associated example for you to download if you want to work it out. You
must use a SQL Server, database, and the relevant tables to ensure the program works. If the
server name does not match the database name or the tables then the program won't run. There
was no way for me to attach a database in the example. Since the databases require a SQL
Server database that will be always available using a connection, I won't use this database again,
so I have not provided the database connection string.
Database table
The database table in my system was like the following,
SELECT without WHERE
You can run the console and you'll see the results on your screen. This is the code where the
SELECT query ran and the output of the columns returned was printed.
146
SELECT with a WHERE
We can at the same time add a few more parameters to the SELECT query so that only the data
we want would be extracted from the database. For example, if we add a WHERE clause to the
SELECT query, the following result would be generated.
Inserting the data
Once done, you can move on to the next stage. This part is related to the second command,
where we add the records to the table. This statement, when executed, would add the data to the
table. The table is now like this:
In this example, what happens is that the preceding code is used in our application. I will also
provide the code used in this console application. Comments have been added with each block
so you understand how the code works.
147
Source code
1. using System;
2. using System.Data;
3. using System.Data.SqlClient;
4. using System.Collections.Generic;
5. using System.Linq;
6. using System.Text;
7. using System.Threading.Tasks;
8.
9. namespace SqlTest_CSharp {
10.
class Program {
11.
static void Main(string[] args) {
12.
// Create the connection to the resource!
13.
// This is the connection, that is established and
14.
// will be available throughout this block.
15.
using(SqlConnection conn = new SqlConnection()) {
16.
// Create the connectionString
17.
// Trusted_Connection is used to denote the connection uses Wi
ndows Authentication
18.
conn.ConnectionString = "Server=[server_name];Database=[databa
se_name];Trusted_Connection=true";
19.
conn.Open();
20.
// Create the command
21.
SqlCommand command = new SqlCommand("SELECT * FROM TableName W
HERE FirstColumn = @0", conn);
22.
// Add the parameters.
23.
command.Parameters.Add(new SqlParameter("0", 1));
24.
25.
/* Get the rows and display on the screen!
26.
* This section of the code has the basic code
27.
* that will display the content from the Database Table
28.
* on the screen using a SqlDataReader. */
29.
30.
using(SqlDataReader reader = command.ExecuteReader()) {
31.
Console.WriteLine("FirstColumn\tSecond Column\t\tThird Col
umn\t\tForth Column\t");
32.
while (reader.Read()) {
33.
Console.WriteLine(String.Format("{0} \t | {1} \t | {2}
\t | {3}",
34.
reader[0], reader[1], reader[2], reader[3]));
35.
}
36.
}
37.
Console.WriteLine("Data displayed! Now press enter to move to
the next section!");
38.
Console.ReadLine();
39.
Console.Clear();
40.
148
41.
/* Above code was used to display the data from the Database t
able!
42.
43.
* This following section explains the key features to use
* to add the data to the table. This is an example of another
44.
* SQL Command (INSERT INTO), this will teach the usage of par
ameters and connection.*/
45.
46.
47.
48.
49.
50.
51.
Console.WriteLine("INSERT INTO command");
// Create the command, to insert the data into the Table!
// this is a simple INSERT INTO command!
SqlCommand insertCommand = new SqlCommand("INSERT INTO TableNa
me (FirstColumn, SecondColumn, ThirdColumn, ForthColumn) VALUES (@0, @1, @2, @
3)", conn);
52.
53.
// In the command, there are some parameters denoted by @, you
can
54.
// change their value on a condition, in my code,
they're hardcoded.
55.
56.
57.
insertCommand.Parameters.Add(new SqlParameter("0", 10));
insertCommand.Parameters.Add(new SqlParameter("1", "Test Colum
n"));
58.
insertCommand.Parameters.Add(new SqlParameter("2", DateTime.No
w));
59.
60.
61.
insertCommand.Parameters.Add(new SqlParameter("3", false));
// Execute the command
and print the values of the columns affected through
62.
// the command executed.
63.
64.
Console.WriteLine("Commands executed! Total rows affected are
" + insertCommand.ExecuteNonQuery());
65.
Console.WriteLine("Done! Press enter to move to the next step"
);
66.
Console.ReadLine();
67.
Console.Clear();
68.
69.
/* In this section, there is an example of the Exception case
70.
* Thrown by the SQL Server, that is provided by SqlException
71.
* Using that class object, we can get the error thrown by SQL
Server.
72.
73.
74.
* In my code, I am simply displaying the error! */
Console.WriteLine("Now the error trial!");
149
75.
76.
77.
// try block
try {
// Create the command to execute! With the wrong name of t
he table (Depends on your Database tables)
78.
SqlCommand errorCommand = new SqlCommand("SELECT * FROM so
meErrorColumn", conn);
79.
// Execute the command, here the error will pop up!
80.
// But since we're catching the code block's errors, it wi
ll be displayed inside the console.
81.
errorCommand.ExecuteNonQuery();
82.
}
83.
// catch block
84.
catch (SqlException er) {
85.
// Since there is no such column as someErrorColumn (Depen
ds on your Database tables)
86.
// SQL Server will throw an error.
87.
Console.WriteLine("There was an error reported by SQL Serv
er, " + er.Message);
88.
}
89.
}
90.
// Final step, close the resources flush
to
dispose
of
them. ReadLine to prevent the console from closing.
91.
Console.ReadLine();
92.
}
93.
}
94. }
Exception Handling in C#
Exception handling in C#, supported by the try catch and finally block is a mechanism to detect
and handle run-time errors in code. The .NET framework provides built-in classes for common
exceptions. The exceptions are anomalies that occur during the execution of a program. They
can be because of user, logic or system errors. If a user (programmer) does not provide a
mechanism to handle these anomalies, the .NET runtime environment provides a default
mechanism, which terminates the program execution.
try..catch..finally
C# provides three keywords try, catch and finally to implement exception handling. The try
encloses the statements that might throw an exception whereas catch handles an exception if
one exists. The finally can be used for any cleanup work that needs to be done.
150
Try..catch..finally block example:
1. try
2. {
3. // Statement which can cause an exception.
4. }
5. catch(Type x)
6. {
7. // Statements for handling the exception
8. }
9. finally
10. {
11. //Any cleanup code
12. }
If any exception occurs inside the try block, the control transfers to the appropriate catch block
and later to the finally block.
But in C#, both catch and finally blocks are optional. The try block can exist either with one or
more catch blocks or a finally block or with both catch and finally blocks.
If there is no exception occurred inside the try block, the control directly transfers to finally block.
We can say that the statements inside the finally block is executed always. Note that it is an error
to transfer control out of a finally block by using break, continue, return or goto.
In C#, exceptions are nothing but objects of the type Exception. The Exception is the ultimate
base class for any exceptions in C#. The C# itself provides couple of standard exceptions. Or
even the user can create their own exception classes, provided that this should inherit from either
Exception class or one of the standard derived classes of Exception class like
DivideByZeroExcpetion to ArgumentException etc.
Uncaught Exceptions
The following program will compile but will show an error during execution. The division by zero
is a runtime anomaly and program terminate with an error message. Any uncaught exceptions in
the current context propagate to a higher context and looks for an appropriate catch block to
handle it. If it can't find any suitable catch blocks, the default mechanism of the .NET runtime will
terminate the execution of the entire program.
1.
2.
3.
4.
5.
6.
7.
8.
9.
//C#: Exception Handling
//Author: rajeshvs@msn.com
using System;
class MyClient
{
public static void Main()
{
int x = 0;
int div = 100/x;
151
10.
11.
12. }
Console.WriteLine(div);
}
The modified form of the above program with exception handling mechanism is as follows. Here
we are using the object of the standard exception class DivideByZeroException to handle the
exception caused by division by zero.
1. //C#: Exception Handling
2. using System;
3. class MyClient
4. {
5.
public static void Main()
6.
{
7.
int x = 0;
8.
int div = 0;
9.
try
10.
{
11.
div = 100 / x;
12.
Console.WriteLine("This linein not executed");
13.
}
14.
catch (DivideByZeroException)
15.
{
16.
Console.WriteLine("Exception occured");
17.
}
18.
Console.WriteLine($"Result is {div}");
19.
}
20. }
Result from above code is show below:
152
In the above case, the program does not terminate unexpectedly. Instead, the program control
passes from the point where exception occurred inside the try block to the catch blocks. If it finds
any suitable catch block, executes the statements inside that catch and continues with the normal
execution of the program statements.
If a finally block is present, the code inside the finally block will get also be executed.
1. //C#: Exception Handling
2. using System;
3. class MyClient
4. {
5.
public static void Main()
6.
{
7.
int x = 0;
8.
int div = 0;
9.
try
10.
{
11.
div = 100/x;
12.
Console.WriteLine("Not executed line");
13.
}
14.
catch(DivideByZeroException)
15.
{
16.
Console.WriteLine("Exception occured");
17.
}
18.
finally
19.
{
20.
Console.WriteLine("Finally Block");
21.
}
22.
Console.WriteLine($"Result is {div}");
23.
}
24. }
Remember that in C#, the catch block is optional. The following program is perfectly legal in C#.
1. //C#: Exception Handling
2. using System;
3. class MyClient
4. {
5.
public static void Main()
6.
{
7.
int x = 0;
8.
int div = 0;
9.
try
10.
{
11.
div = 100/x;
12.
Console.WriteLine("Not executed line");
13.
}
14.
finally
153
15.
16.
17.
18.
19.
20. }
{
Console.WriteLine("Finally Block");
}
Console.WriteLine($"Result is {div}");
}
But in this case, since there is no exception handling catch block, the execution will get terminated.
But before the termination of the program statements inside the finally block will get executed. In
C#, a try block must be followed by either a catch or finally block.
Multiple Catch Blocks
A try block can throw multiple exceptions, which can handle by using multiple catch blocks.
Remember that more specialized catch block should come before a generalized one. Otherwise,
the compiler will show a compilation error.
1. //C#: Exception Handling: Multiple catch
2. using System;
3. class MyClient
4. {
5.
public static void Main()
6.
{
7.
int x = 0;
8.
int div = 0;
9.
try
10.
{
11.
div = 100 / x;
12.
Console.WriteLine("Not executed line");
13.
}
14.
catch (DivideByZeroException de)
15.
{
16.
Console.WriteLine("DivideByZeroException");
17.
}
18.
catch (Exception)
19.
{
20.
Console.WriteLine("Exception");
21.
}
22.
finally
23.
{
24.
Console.WriteLine("Finally Block");
25.
}
26.
Console.WriteLine($"Result is {div}");
27.
}
28. }
154
Catching all Exceptions
By providing a catch block without brackets or arguments, we can catch all exceptions occurred
inside a try block. Even we can use a catch block with an Exception type parameter to catch all
exceptions happened inside the try block since in C#, all exceptions are directly or indirectly
inherited from the Exception class.
1. //C#: Exception Handling: Handling all exceptions
2. using System;
3. class MyClient
4. {
5.
public static void Main()
6.
{
7.
int x = 0;
8.
int div = 0;
9.
try
10.
{
11.
div = 100 / x;
12.
Console.WriteLine("Not executed line");
13.
}
14.
catch
15.
{
16.
Console.WriteLine("oException");
17.
}
18.
Console.WriteLine($"Result is {div}");
19.
}
20. }
The following program handles all exception with Exception object.
1. //C#: Exception Handling: Handling all exceptions
2. using System;
3. class MyClient
4. {
5.
public static void Main()
6.
{
7.
int x = 0;
8.
int div = 0;
9.
try
10.
{
11.
div = 100 / x;
12.
Console.WriteLine("Not executed line");
13.
}
14.
catch (Exception)
15.
{
16.
Console.WriteLine("oException");
17.
}
18.
Console.WriteLine($"Result is {div}");
155
19.
20. }
}
Throwing an Exception
In C#, it is possible to throw an exception programmatically. The 'throw' keyword is used for this
purpose. The general form of throwing an exception is as follows.
1. throw exception_obj;
For example, the following statement throws an ArgumentException explicitly.
1. throw new ArgumentException("Exception");
2.
3. //C#: Exception Handling:
4. using System;
5. class MyClient
6. {
7.
public static void Main()
8.
{
9.
try
10.
{
11.
throw new DivideByZeroException("Invalid Division");
12.
}
13.
catch (DivideByZeroException)
14.
{
15.
Console.WriteLine("Exception");
16.
}
17.
Console.WriteLine("LAST STATEMENT");
18.
}
19. }
Re-throwing an Exception
The exceptions, which we caught inside a catch block, can re-throw to a higher context by using
the keyword throw inside the catch block. The following program shows how to do this.
1.
2.
3.
4.
5.
6.
//C#: Exception Handling: Handling all exceptions
using System;
class MyClass
{
public void Method()
{
156
7.
try
8.
{
9.
int x = 0;
10.
int sum = 100 / x;
11.
}
12.
catch (DivideByZeroException)
13.
{
14.
throw;
15.
}
16.
}
17. }
18. class MyClient
19. {
20.
public static void Main()
21.
{
22.
MyClass mc = new MyClass();
23.
try
24.
{
25.
mc.Method();
26.
}
27.
catch (Exception)
28.
{
29.
Console.WriteLine("Exception caught here");
30.
}
31.
Console.WriteLine("LAST STATEMENT");
32.
}
33. }
Standard Exceptions
There are two types of exceptions: exceptions generated by an executing program and exceptions
generated by the common language runtime. System.Exception is the base class for all
exceptions in C#. Several exception classes inherit from this class including ApplicationException
and SystemException. These two classes form the basis for most other runtime exceptions. Other
exceptions that derive directly from System.Exception include IOException, WebException etc.
The common language runtime throws SystemException. The ApplicationException is thrown by
a user program rather than the runtime. The SystemException includes the
ExecutionEngineException, StaclOverFlowException etc. It is not recommended that we catch
SystemExceptions nor is it good programming practice to throw SystemExceptions in our
applications.
•
•
•
•
System.OutOfMemoryException
System.NullReferenceException
Syste.InvalidCastException
Syste.ArrayTypeMismatchException
157
•
•
•
•
System.IndexOutOfRangeException
System.ArithmeticException
System.DivideByZeroException
System.OverFlowException
User-defined Exceptions
In C#, it is possible to create our own exception class. But Exception must be the ultimate base
class for all exceptions in C#. So the user-defined exception classes must inherit from either
Exception class or one of its standard derived classes.
1. //C#: Exception Handling: User defined exceptions
2. using System;
3. class MyException : Exception
4. {
5.
public MyException(string str)
6.
{
7.
Console.WriteLine("User defined exception");
8.
}
9. }
10. class MyClient
11. {
12.
public static void Main()
13.
{
14.
try
15.
{
16.
throw new MyException("RAJESH");
17.
}
18.
catch (Exception)
19.
{
20.
Console.WriteLine("Exception caught here" + e.ToString());
21.
}
22.
Console.WriteLine("LAST STATEMENT");
23.
}
24. }
Design Guidelines
Exceptions should be used to communicate exceptional conditions. Don't use them to
communicate events that are expected, such as reaching the end of a file. If there's a good
predefined exception in the System namespace that describes the exception condition-one that
will make sense to the users of the class-use that one rather than defining a new exception class
and put specific information in the message. Finally, if code catches an exception that it isn't going
to handle, consider whether it should wrap that exception with additional information before rethrowing it.
158
Course Materials
https://www.tutorialspoint.com/asp.net/asp.net_ado_net.htm
https://www.c-sharpcorner.com/UploadFile/201fc1/sql-server-database-connection-in-csharpusing-adonet/
https://www.c-sharpcorner.com/article/exception-handling-in-C-Sharp/
Activities/Assessment
1. Using the table below, create a WPF Application that will manage employee
records.
159
Module 6
Application Development Concepts
Overview:
To know the process of designing, building, and implementing software
applications. To address the issues of developing an application and know the standards
and guidelines for testing and implementing a java application.
Module Objectives:
After successful Completion of this module, you should be able to:
•
•
•
Know the definition of Application and Application development
Explain the concepts of Application Development and Issues
Apply the different level and kinds of test in the application developed.
160
What is an Application?
An application is simply a computer-based model of some aspect of the real world designed to
solve a specific set of problems. Computing technology has given rise to an ever-increasing
number of applications in almost every aspect of life, from the most mundane address book s,
to the information systems required to track the business processes of an entire enterprise.
Regardless of the size or complexity of applications, they all have a common purpose: the
manipulation, analysis, and persistence of data.
What Is Application Development?
Application development is the process of designing, building, and implementing software
applications. It can be done by massive organizations with large teams working on projects, or by
a single freelance developer. Application development defines the process of how the application
is made, and generally follows a standard methodology.
There are lots of factors that go into how application development is done. You must consider the
size of the project, how specific the requirements are, how much the customer will want to change
things, how large the development team is, how experienced the development team is, and the
deadline for the project. Application development is closely linked with the software development
life-cycle (SDLC).
Identifying the Issues
Given this general definition of an application, it is clear that data management plays a large
role in any application. As such, every application must address at least some of the following
issues:
Persistence
The data must be stored for an extended period of time.
Integrity
The data must be correct, according to some defined set of rules.
Concurrency
Coordinating read and change requests from multiple users.
Scalability
The application must scale in terms of number of users, volume of
data, and data complexity.
Performance
Providing efficient access to the application data.
Recovery
Ensuring that the data can survive application and system failures.
Security
Preventing unauthorized access or manipulation of the application
data.
161
Reporting
Providing general analysis and presentation of the application data
to support decision making within the organization.
Integration
Allowing the application to interact with other software systems.
Presentation
Providing a user interface for entry and manipulation of the
application data.
In addition to these problems, the application will inevitably encounter change of some form:
Requirements Change
Modifying the application to fit new or changing business needs.
Environment Change
Reacting to changes in the hardware or software environment.
In building applications that handle all these issues, we also encounter development process
issues that must be addressed:
Developer
Productivity
Ensuring maximum productivity of application team members.
Developer Training
Training team members on the platforms and technologies to be
used.
Application Quality
Ensuring the application meets requirements and functionality.
Deployment
Providing installation and deployment for the application.
Maintenance
Providing a maintenance path for deployed applications.
Clearly, application development in general is an extremely complex problem. The more
complex the application, the more difficult the solution to these problems becomes.
Fortunately, these solutions can, for the most part, be generally implemented in systems -level
software that all applications can utilize. Many of these issues, such as
persistence, concurrency, scalability, and others, are already addressed to varying degrees by
existing systems; however, there are still many issues that arise when developing applications
against these systems:
Schema Duplication
Presentation layers often duplicate the structures and logic already
present in the database schema.
Complex Business
Rules
Existing systems often do not provide effective support for
complex business rules. Client-Side Enforcement of Business
Rules - Presentation layers must provide initial enforcement
of business rules.
162
Client-Side Buffering
Presentation layers must provide a mechanism for data retrieval,
display, entry and translation.
Traditionally, these problems have been resolved on a case-by-case basis within each
application. The result is large amounts of application-specific code that is difficult to produce
and maintain. If a general purpose solution to these issues can be found, it can be automated,
just as many of the issues relating to data management have been automated
by Database Management Systems (DBMSs).
Various Software Testing Concepts
Enlisted below are the various Software Testing Concepts along with their comparison.
Difference Between Test Plan And Test Strategy
Test Strategy and Test plan are two important documents in the testing life cycle of any project.
Here we are trying to give you an in-depth knowledge of test strategy and test plan documents.
Test Plan
A Test Plan can be defined as a document that defines the scope, objective, and approach to test
the software application. The Test Plan is a term and a deliverable.
The Test Plan is a document that lists all the activities in a QA project, schedules them, defines
the scope of the project, roles & responsibilities, risks, entry & exit criteria, test objective, and
anything else that you can think of.
The Test Plan is as I like to call a ‘super document’ that lists everything there is to know and need.
Please check this link for more information and a sample.
The Test Plan will be designed based on the requirements. While assigning work to the test
engineers, due to some reasons one of the testers gets replaced by another one. Here, the Test
Plan gets updated.
The Test strategy outlines the testing approach and everything else that surrounds it. It is different
from the Test Plan, in the sense that a Test strategy is only a subset of the test plan. It is a
hardcore test document that is to an extent generic and static. There is also an argument about
at what levels test strategy or plan is used- but I really do not see any discerning difference.
Example: The Test Plan gives information about who is going to test at what time.
For Example, Module 1 is going to be tested by “X tester”. If tester Y replaces X for some reason,
the test plan has to be updated.
Test Plan Document
Test Plan is a document that provides complete information about testing tasks related to a
Software Project. It provides details like Scope of the testing, Types of testing, Objectives, Test
Methodology, Testing Effort, Risks & Contingencies, Release Criteria, Test Deliverables, etc. It
keeps track of possible tests that will be run on the system after coding.
The test plan is obviously set to change. Initially, a draft test plan will be developed based on
project clarity at that time. This initial plan will get modified as the project progresses. Test team
163
Manager or Test Lead can prepare the test plan document. It describes the Specifications and is
subject to change based on the same.
What to test, when to test, who will test, and how to test will be defined in the test plan. Test Plan
will sort out a list of issues, dependencies, and the underlying risks.
Separate test plans can be created for specific testing types like system testing, system
integration testing, user acceptance testing, etc.
Another approach is to have separate test plans for functional and non-functional testing. In this
approach performance, testing will have a separate test plan.
Contents of Test plan Document (IEEE-829 test plan structure)
It is difficult to draw a clear format for the test plan. The test plan format may vary depending on
the project in hand. IEEE has defined a standard for test plans which are described as the IEEE829 test plan structure.
Please find below IEEE recommendations for a standard test plan content:
1. Test Plan Identifier
2. Introduction
3. Test Items
4. Software Risk Issues
5. Features to be tested
6. Features not to be tested
7. Approach
8. Item Pass/Fail Criteria (or) Acceptance Criteria
9. Suspension Criteria and Resumption Requirements
10. Test Deliverables
11. Test Tasks
12. Environmental Requirements
13. Staffing and Training needs
14. Responsibilities
15. Schedule
16. Approvals
Test Strategy
Test Strategy is a set of guidelines that explain the test design and determine how testing needs
to be done.
Example: A Test Strategy includes details like “Individual modules are to be tested by the test
team members”. In this case, who tests it does not matter – so it’s generic and the change in the
team member does not have to be updated, keeping it static.
Test Strategy Document
The purpose of the test strategy is to define the testing approach, the types of tests, test
environments, and tools to be used for testing and the high-level details of how the test strategy
will be aligned with other processes. The test strategy document is intended to be a living
document and will be updated** when we get more clarity on Requirements, SLA parameters,
Test environment and Build management approach, etc.
164
Test strategy is intended for the complete project team that comprises of Project Sponsors,
Business SMEs, Application/ Integration Development, System Integration partners, Data
Conversion Teams, Build/Release Management Teams such as technical leads, architecture
leads, and deployment and infrastructure teams.
** Some argue that test strategy once defined should never be updated. In most testing projects
usually, it gets updated as the project progress.
Below are the important sections that a test strategy document should have:
#1) Project Overview
This section can begin by giving an overview of the organization followed by a brief description of
the project in hand. It can include below details
•
•
What was the need for the project?
What objectives the project will attain?
Table of Acronyms: It is better to include a table with acronyms that the document reader might
come up with while referring to the document.
#2) Requirements Scope
Requirement scope can include Application Scope and Functional scope
Application Scope defines the system under test and the impact on the system due to new or
changed functionality. Related systems can also be defined.
System
Impact (New or Changed functionality)
Related System
System A
New enhancements and bug fixes
• System B
• System C
Functional Scope defines the impact on different modules within the system. Here each related
system with respect to functionality will be explained.
System
Module
Functionality
Related System
System C
Module 1
Functionality 1
System B
Functionality 2
System C
#3) High-Level Test Plan
165
Test Plan is a separate document. In the test strategy, a high-level test plan can be included. A
high-level test plan can include test objectives and test scope. Test scope should define both in
scope and out of scope activities.
#4) Test Approach
This section describes the testing approach that will be followed during the testing life cycle.
As per the above diagram testing will be conducted in two phases i.e. Test Strategy & Planning
and Test Execution. Test Strategy & Planning phase will be one time for an overall program
whereas Test execution phases will be repeated for each Cycle of the overall program. The above
diagram shows different stages and deliverables (outcome) in each phase of the execution
approach.
Test approach should include below sub-sections
a) Test Schedule: Explain the proposed project timeline in this subsection
b) Functional Testing Approach: Using this subsection provides an overview of each phase
and the respective entry and exit criteria. Different testing phases are Unit testing, System testing,
System Integration testing, User Acceptance Testing, and End-to-End testing.
c) Testing Key Performance Indicators :
•
Test case prioritization: Define the test case prioritization approach so that in
case of time constraints, high priority scenarios can be executed by the test team.
There should be an agreement between project stakeholders regarding the
possible risks involved in not executing all the planned scenarios.
166
•
•
Defect prioritization: Defect prioritization strategy is the next topic to cover here.
Define priority level and give the description to each level like critical, high,
medium, etc. Also
Defect Turnaround Time: Defect turnaround time is defined as the time between
when the defect was first raised and when the defect is fixed and comes for a
retest. Quick turnaround ensures speedy testing and adherence to the project
timeline. For each defect priority level, define the turnaround time.
Priority Level
Defect Turnaround Time
1 - Critical
Response Time: 2 hours or less
Fix Ready for Migration: 1 business days or less
#5) Test Coverage
This section describes the processes that the QA team will follow in order to optimize the coverage
of business/functional requirements in test scenarios and test cases. Requirement Traceability
Matrix: (RTM) can be used to trace all the requirements with respective test scenarios and test
cases.
#6) Test Environment
Define the different QA environments available. Mention what testing will be done in which
environment and by whom. Create an environment backup plan to take care of emergencies.
Access to each environment should be regulated and called out with clarity.
Testing tools that are going to be used also can be mentioned in this section.
Activity
Tool
Remarks
Test management
HP ALM
Mention the reason for using this tool
Defect management
JIRA
Mention the reason for using this tool
#7) QA Deliverables and Metrics
List out all the QA deliverables
S. No.
Deliverable
1
Test Strategy Document
2
Requirement Traceability Matrix
3
ST Test Scripts
167
S. No.
Deliverable
4
Test Summary Report
5
Automation eligible scenario list
List out all the QA metrics
Metric
Reports in which
unit of the metrics to be
measure used
Metric
Definition
Metric
Formula
Requirements
Coverage
Metrics(RCM)
The
coverage of
requirements
by QA
Ratio of # of %
requirements
tested to # of
requirements
identified
Weekly QA status
report,
Test
summary
report
Test
Coverage
The
coverage of
test
case
executed
Ratio
of %
number
of
test
cases
executed
/number
of
test
cases
planned
Daily
Execution report,
Weekly QA status
report,
Test
summary
report
#
Metric Name
1
2
#8) Defect Management
Clearly define a defect management strategy by creating a defect workflow, defect tracking
methodology & defect triage process. Mention defect responsibility for each tester's roles.
Periodic defect analysis and root cause analysis will improve the overall quality of testing
#9) Communication Management
Set guidelines for status reports, status meetings, and onsite-offshore communication.
#10) Assumptions, Risks, and Dependencies
168
Describe assumptions on which the project is based. These may include timing, resources, and
system capabilities. Describe any dependencies such as other projects, availability of temporary
resources, other deadlines that may impact the project.
#11) Appendix
Include stuff like Roles & Responsibilities, Work Time Zone, and References in this section
Further reading => Guide to Writing a Good Test Strategy document.
Test Plan Vs Test Strategy
TEST PLAN
TEST STRATEGY
It is derived from software requirement
specification(SRS).
It is derived from the Business
Requirement document(BRS).
It is prepared by the test lead or manager.
It is developed by the project manager
or the Business analyst.
Test plan id, features to be tested, test
techniques, testing tasks, features pass or
fail criteria, test deliverables,
responsibilities, and schedule, etc. are the
components of the test plan.
Objectives and scope, documentation
formats, test processes, team
reporting structure, client
communication strategy, etc. are the
components of test strategy.
If there is a new feature or a change in the
requirement that is happened then the test
plan document gets updated.
Test strategy maintains the standards
while preparing the document. It is
also called as Static document.
We can prepare the test plan individually.
In smaller projects, test strategy is
often found as a section of a test plan.
We can prepare a Test plan at the project
level.
We can use Test strategy at multiple
projects.
It describes how to test , when to test, who
will test and what to test.
It describes what type of technique to
follow and which module to test.
We can describe about the specifications
by using a Test Plan.
Test strategy describes about the
general approaches.
Test Plan will change over the course of the
project.
Test Strategy usually will not change
once approved.
169
TEST PLAN
TEST STRATEGY
Test plan is written after requirement sign
off.
Test strategy is made before the test
plan.
Test plans can be of different types. There
will be a master test plan and separate test
plan for different types of testing like system
test plan, performance test plan, etc.
There will be only one test strategy
document for a project.
Test plan should be clear and concise.
Test strategy provides overall
guidance for the project in hand.
The difference between these two documents is subtle. A test strategy is a high-level static
document about the project. On the other hand, the test plan will specify what to test, when to
test, and how to test.
Difference Between Test Case And Test Script
In my opinion, these two terms can be used interchangeably. Yes, I am saying there is no
difference. The test case is a sequence of steps that help us perform a certain test on the
application. The test script is also the same thing.
TEST CASE
TEST SCRIPT
It is a step by step by procedure that
is used to test an application
It is a set of instructions to test
an application automatically.
The term Test Case is used in the
manual testing environment.
The term Test Script is used in
automation testing environment.
It is done manually.
It is done by scripting format.
It is developed in the form of
templates.
It is developed in the form of
scripting.
Test case template includes Test
Suit ID, Test Data, Test procedure,
Actual results, Expected results etc.
In Test Scrip,t we can use
different commands to develop
script.
170
Now,
is one
Is used to test an application.
It is also used to test an
application.
It is the base form to test an
application in sequence.
Once we develop, the script will
run it multiple times until the
requirement is changed.
Example: We need to verify the
login button in an application,
The steps include:
a) Launch the application.
b) Verify if the login button is
displaying or not.
Example: We want to click an
image button in an application.
The script includes:
a) Click the Image Button.
there
school of thought that a test case is a term used in the manual testing environment and test script
is used in an automation environment. This is partly true, because of the comfort level of the
testers in the respective fields and also on how the tools refer to the tests (some call test scripts
and some call them to test cases).
So in effect, test script and test case both are steps to be performed on an application to validate
its functionality whether manually or through automation.
Difference Between Test Scenario and Test Condition
Test Scenario: It is a way to define all the possible ways to test an application. It is a single
statement to cover all possible ways to test an application.
Test Condition: Test Condition is the specification that a tester must follow for testing an
Application.
This is a one-line pointer that testers create as an initial, transitional step into the test design
phase. This is mostly a one-line definition of “What” we are going to test with respect to a certain
feature. Usually, test scenarios are input for the creation of test cases.
In agile projects, Test scenarios are the only test design outputs and no test cases are written
following these. A Test scenario might result in multiple tests.
Examples of Test Scenarios:
•
•
•
Validate if a new country can be added by the Admin
Validate if an existing country can be deleted by the Admin
Validate if an existing country can be updated
Test conditions, on the other hand, are more specific. It can be roughly defined as the aim/goal
of a certain test.
171
Example Test Condition: In the above example, if we were to test the scenario 1, we can test
the following conditions:
•
•
•
Enter the country name as “India”(valid )and check for the addition of the country
Enter a blank and check if the country gets added.
In each case, the specific data is described and the goal of the test is much more
precise.
TEST SCENARIO
TEST CONDITION
It is a process to test an application with
all possible ways.
Test conditions are the static rules
should be followed to test an
application.
Test scenarios are an input for the
creation of test cases.
It gives the main goal to test an
application.
Test scenario covers all possible cases
to test an application.
Test condition is very specific.
It reduces the complexity.
It makes a system bug free.
Test scenario can be a single or a group
of test cases.
It is the goal of test cases.
By writing scenarios it will be easy to
understand the functionality of an
application.
Test condition is very specific.
These are one line statements to explain
what we are going to test.
Test Condition describes the main goal
to test an application.
Examples test scenarios:
#1) Validate if a new country can be
added by the Admin.
#2) Validate if an existing country can be
deleted by the admin.
#3) Validate if an existing Country can be
updated.
Examples test Conditions:
#1) Enter the country name as “India”
and check for the addition of the
country.
#2) Leave blank fields and check if the
country gets added.
172
Difference Between Test Procedure and Test Suite
The test procedure is a combination of test cases based on a certain logical reason, like executing
an end-to-end situation or something to that effect. The order in which the test cases are to be
run is fixed.
Test Procedure: It is nothing but the Test Life Cycle. There are 10 steps in the Testing Life Cycle.
They are:
1. Effort Estimation
2. Project Initiation
3. System Study
4. Test plan
5. Design Test Case
6. Test Automation
7. Execute Test Cases
8. Report Defects
9. Regression Testing
10. Analysis and Summary Report
The order of test cases that will combine to form a test procedure would be:
1.
2.
3.
4.
5.
6.
The test to check the login
The test to compose an email
The test to attach one/more attachments
Formatting the email in the required way by using various options
Adding contacts or email addresses to the To, BCC, CC fields
Sending an email and making sure it is showing in the “Sent Mail” section
All the test cases above are grouped to achieve a certain target at the end of them. Also, test
procedures have a few test cases combined at any point in time.
The Test suite, on the other hand, is the list of all the test cases that have to be executed as a
part of a test cycle or a regression phase, etc. There is no logical grouping based on functionality.
The order in which the constituent test cases get executed may or may not be important.
Test Suite: The Test Suite is a container that has a set of tests which help the testers in executing
and reporting the test execution status. It can take any of the three states i.e. Active, in progress
and completed.
Example of the Test Suite: If an application’s current version is 2.0. The previous version 1.0
might have had 1000 test cases to test it entirely. For version 2 there are 500 test cases to just
test the new functionality that is added in the new version.
So, the current test suite would be 1000+500 test cases that include both regression and the new
functionality. The suite is a combination too, but we are not trying to achieve a target function.
Test suites can contain 100s or even 1000s of test cases.
173
TEST PROCEDURE
TEST SUITE
It is a combination of test cases to test an
application.
It is a group of test cases to test an
application.
It is a logical grouping based on the
functionality.
There is no logical grouping based
on the functionality.
Test Procedures are deliverable products in
the software development process.
It is executed as a part of the test
cycle or regression.
The order of execution is fixed.
The order of execution may not be
important.
Test procedure contains end to end test
cases.
Test suite contains all new features
and regression test cases.
Test procedures are coded in a new language
called TPL(Test Procedure language).
Test suite contains manual test
cases or automation scripts.
Creation of Test Procedures is based on the
end to end test flow.
Test suites are created based on
the cycle or based on the scope.
Unit Testing
Writing a test case is always an important part of software testing. Testing software is
always a real challenges for developers and testers, because many types of test cases
exists and also come in so many different shapes and sizes. In order to learn how to
write good test cases, we must first understand what is a test case and why do we need
it. Later we will learn how to write Unit Test using C# language. So let's learn that first
What do you mean by a Unit test ?
In the software development process Unit Tests basically test individual parts ( also called as Unit
) of code (mostly methods) and make it work as expected by programmer. A Unit Test is a code
written by any programmer which test small pieces of functionality of big programs. Performing
unit tests is always designed to be simple, A "UNIT" in this sense is the smallest component of
the large code part that makes sense to test, mainly a method out of many methods of some
class. Generally the tests cases are written in the form of functions that will evaluate and
determine whether a returned value after performing Unit Test is equals to the value you were
174
expecting when you wrote the function. The main objective in unit testing is to isolate a unit part
of code and validate its to correctness and reliable.
Why do we need Unit test?
One of the most valuable benefits of using Unit Tests for your development is that it may give you
positive confidence that your code will work as you have expected it to work in your development
process. Unit Tests always give you the certainty that it will lead to a long term development phase
because with the help of unit tests you can easily know that your foundation code block is totally
dependable on it.
There are few reasons that can give you a basic understanding of why a developer needs to
design and write out test cases to make sure major requirements of a module are being validated
during testing,
•
•
•
•
•
Unit testing can increase confidence and certainty in changing and maintaining code in
the development process.
Unit testing always could find problems in early stages in the development cycle.
Codes are more reusable, reliable, and clean.
Development becomes faster.
Easy to automate.
Let us start the show – create your first Unit test (step by Step)
Unit testing is a way or you can say that process with the help of this a programmer can make
themselves sure that their code that is written is fully functional, clean, reliable and will definitely
work the same way as it is supposed to work.
One of the fundamental principles of adopting unit testing is to follow a TDD (Test Driven
Development) aproach where we have to write tests case first, and then write the simple code
that will make the test pass. Here I am going to follow just the opposite approach to make you
learn how to write and Test code first with a simple example. Later we will discuss about TDD(Test
Driven Development) concept. In this article we are going to follow different approach where we
will write simple code first, and then create the Unit Tests based on the possible situations. As
discussed earlier, we can also write Tests first, and then write the code that will make the test
pass. It depends upon individuals what and which one of the ways they love to follow to test code.
Here I’ve written a basic program which can be easily understandable by any novice who has just
started to learn C# and wants to learn how to write unit tests.
1. public class BasicMaths {
2.
public double Add(double num1, double num2) {
3.
return num1 + num2;
4.
}
5.
public double Substract(double num1, double num2) {
175
6.
7.
8.
9.
10.
11.
12.
return num1 - num2;
}
public double divide(double num1, double num2) {
return num1 / num2;
}
public double Multiply(double num1, double num2) {
// To trace error while testing, writing + operator instead of * opera
tor.
13.
return num1 + num2;
14.
}
15. }
In this program, you can see that there are four basic math functions: Add, Subtract, Divide and
Multiply. All the functions have two double datatype parameters.
MS Unit tests
To test the above four methods, we are going to use Microsoft Testing tools, which is MS Unit
Test. To add MS Unit Test, follow the steps given below.
176
First move to Solution Explorer ( shortcut Ctrl + Alt + L to open Solution Explorer).
•
•
•
Right click on Solution Project Name.
Click Add.
Click New Project.
It will open Add New Project Window. Follow the given steps to create and add Unit Test Project.
•
•
•
Click Test.
Select Unit Test Project from the list of the available templates.
Write the name of the project. Here, we are using BasicMathTest followed by clicking OK
button.
It created BasicMathTest project along with BasicMath Project whose functions need to be tested.
To access all the four methods of BasicMath in test project, we need to add the reference in test
project. Take a look at the image given below to know how to add.
177
•
•
Right click on Reference of MS Unit Test Project.
Click Add Reference.
It will open a Reference Manager Window. To add reference, click Projects – Solutions –
BasicMaths and click OK button.
You can see in the image given below that the reference has been added .
•
•
BasicMath – Having all the functions, which needs to be tested
Microsoft.VisualStudio.QualityTools.UnitTestFramework – It contains all classes and
methods, which provides Unit testing support.
Great, you will get a screen, as shown below.
178
1. using System;
2. using Microsoft.VisualStudio.TestTools.UnitTesting;
3. namespace BasicMathTest {
4.
[TestClass]
5.
public class UnitTest1 {
6.
[TestMethod]
7.
public void TestMethod1() {
8.
// TODO : Write test code
9.
}
10.
}
11. }
What will we do next is add our code to test the functions of BasicMath Project.
First add namespaces.
1. using System;
2. using Microsoft.VisualStudio.TestTools.UnitTesting;
3. using BasicMath;
System namespace contains fundamental classes and base classes, which defines the
commonly-used value and reference data types, events and event handlers, interfaces, attributes
and processing exceptions.
The Microsoft.VisualStudio.TestTools.UnitTesting namespace supplies the classes, which
provides Unit testing support. This namespace contains many attributes, which identifies test
information to the test the engine regarding the data sources, order of method execution, program
management,
agent/host
information
and
the
deployment
of
the
data.
Microsoft.VisualStudio.TestTools.UnitTesting namespace also contains custom unit testing
exceptions.
BasicMath namespace contains all the functions, which are required to be tested like Add,
Subtract, Multiply and Divide
Some requirements that need to be followed,
Test class requirements
The minimum requirements for a test class while writing Unit Test case is given below:
•
•
If you are using Unit Test to write test case then the [TestClass] attribute is highly required
in the Microsoft unit testing framework for any class that contains unit test methods that
you would like to run in Visual Studio Test Explorer.
Each and every test method that you want to run must having the [TestMethod]attribute
above it.
179
Test method requirements
A test method must meet the given requirements:
•
•
•
The method must be defined with the [TestMethod] attribute just above method name.
The method must having return type void.
The method cannot have any parameters.
Writing first Unit Test method
Here, we will write Unit Test methods to verify the behavior of Add method of the BasicMaths
class. The code will look, as shown below.
In a similar way, write test code for all the methods like Subtract, Multiply and Divide. After adding
all the required test methods, our test code will look, as shown below.
1. [TestClass]
2. public class UnitTest1 {
3.
[TestMethod]
4.
public void Test_AddMethod() {
5.
BasicMaths bm = new BasicMaths();
6.
double res = bm.Add(10, 10);
7.
Assert.AreEqual(res, 20);
8.
}
9.
[TestMethod]
10.
public void Test_SubstractMethod() {
11.
BasicMaths bm = new BasicMaths();
12.
double res = bm.Substract(10, 10);
13.
Assert.AreEqual(res, 0);
14.
}
15.
[TestMethod]
16.
public void Test_DivideMethod() {
17.
BasicMaths bm = new BasicMaths();
18.
double res = bm.divide(10, 5);
19.
Assert.AreEqual(res, 2);
20.
}
21.
[TestMethod]
22.
public void Test_MultiplyMethod() {
23.
BasicMaths bm = new BasicMaths();
24.
double res = bm.Multiply(10, 10);
180
25.
26.
27. }
Assert.AreEqual(res, 100);
}
We can see that in every test function, we use Microsoft Unit test framework for the managed
code Assert.AreEqual method to verify that the ending balance is what we expect.
To build and run the test.
•
•
•
Either go to Solution Explorer (Ctrl +Alt+L) and right click on Solution ‘BasicMath’ and click
on Build Solution or go to Build Menu (Alt + B) and Click on Build Solution.
Choose Test Menu -> Run -> All Test or instead of this step, you can follow the given step
also.
Go to Test Explorer and click Run All to run the tests for all the test methods .
As the test is running, the status bar at the top of the Window is animated. At the end of the test
run, the bar turns Green if all the test methods pass or Red, if any of the tests fail.
You should now see something, as shown below.
181
In this case, If the test fails; the test method is moved to the Failed Tests. group. Select the method
in Test Explorer to view the details at the bottom of the Window.
Analyze your test results why it failed
The test result have a detailed message which describes the reason why your test failed. For
the AreEquals method, you can see a message which displays you what was actuallly expected
(the (Expected<XXX>parameter) and what was actually received (the Actual<YYY> parameter).
Correct the bug to make test pass
To correct the error, simply replace +(Plus) with *(Multiply).
1. public double Multiply(double num1, double num2) {
2.
return num1 * num2;
3. }
Rerun Test to check if it is working or not
In Test Explorer, choose Run All to rerun the test. The red/green bar turns green, and the test is
moved
to
the
Passed
Tests
group.
182
Cheers! We learned how to write a Unit test.
TDD(Test Driven Development) Implementation using Unit Testing in C#
As we discussed earlier in this article most developers follow the concept of write Test first then
Code Later approach, we are going to learn TDD approach and to know how to use it.
Test-driven development (TDD) is basically a specification technique and software development
process that always depends on the repetition of short development cycles. In Test-driven
development(TDD) software development process, first the developer writes an automated test
case which is also called as initially failing test case that defines a desired improvement or new
function, then writes the minimum amount of code to pass that test, and finally use the refactors
concept in the new code to make it acceptable standards.
183
One of the advantages of using Test-driven development (TDD) is that it enables developers to
take small steps while writing software programs. For example, assume you have added some
new functional code in your running projects, and then compile, and then test it. There are high
chances that your tests will be broken by defects that exist in the new code of your programs.
With the help of TDD concept It is much easier for a developer to find and then fix those defects
if you’ve written two new lines of code then two thousand lines of codes. It is generally prefered
among programmers to add some few new lines of functional code before they recompile and
rerun tests.
The motto of Test-Driven Development is Red, Green, Refactor.
•
•
•
Red: Create a test and make it fail.
Green: Make the test pass by any means necessary.
Refactor: Change the code to remove duplication in your project and to improve the design
while ensuring that all tests still pass.
The Red/Green/Refactor cycle is repeated very quickly for each new unit of code.
Let’s Implement TDD using MS Unit Testing
Let’s take the exact same sample of code which we’ve used earlier in this article. We will create
four basic functions like Add, Subtract, Multiply and Divide, which will need to be tested. In an
earlier example, we have written the code first, then Unit Test later but as this is TDD
implementation; we will write Unit Test first, then we will write the code later.
To write Unit Test, follow the steps given in the image given below.
•
•
•
Create new project. Click on Test.
Click on Unit Test Project
Write Project name. Eg – BasicMathTDDTest followed by clicking OK button
184
You will get the default code template, as given below to write your test code.
1. using System;
2. using Microsoft.VisualStudio.TestTools.UnitTesting;
3. namespace BasicMathTDDTest {
4.
[TestClass]
5.
public class UnitTest1 {
6.
[TestMethod]
7.
public void Test_Method1() {
8.
// TODO : Add test logic here
9.
}
10.
}
11. }
Here, we are going to write test code first before writing the actual code, which needs to be tested.
185
The code will look, as shown below.
1. public class UnitTest1 {
2.
[TestMethod]
3.
public void Test_AddMethod() {
4.
BasicMaths bm = new BasicMaths();
5.
double res = bm.Add(20.50, 20.50);
6.
Assert.AreEqual(41, res);
7.
}
8.
[TestMethod]
9.
public void Test_MultiplyMethod() {
10.
BasicMaths bm = new BasicMaths();
11.
double res = bm.Multiply(10, 10);
12.
Assert.AreEqual(100, res);
13.
}
14. }
As you can see that there are two test methods- Test_AddMethod and Test_MultiplyMethod and
both the methods are using BasicMaths class, Add and Multiply method, which are not yet
defined. When we run this Application, you will get an error, as given below.
To make MS Unit Test run, we need to create BasicMaths class and add reference to Unit Test
project. Follow the steps given below to know how to create BasicMaths class and add reference
to MS Unit Test Project.
•
Right click on Solution ‘BasicMathTDDTest’.
186
•
•
Click ADD.
Click New Project.
It will open a Add New Project Window, where you have to follow the steps given below.
•
•
•
Click Visual C# (If you are writing code in C# language)
Click Console Application.
Write the name of the project. Here, the project name is BasicMath and click OK button
187
Now, write Add and Multiply Method under BasicMaths class for which we have already written
MS Unit Test. The code will look, as shown below.
1. public class BasicMaths {
2.
public double Add(double num1, double num2) {
3.
return num1 + num2;
4.
}
5.
public double Multiply(double num1, double num2) {
6.
return num1 + num2;
7.
}
After writing the code, you can see that there are 0 references of BasicMaths class as well as Add
method function but these functions are already being used in MS Unit Test project. To make it
accessible, we need to add this project to MS Unit Test Project reference.
188
Once you add reference, its time to run the Test. To run the Test, you can either go to Test ->
Run -> All Test or move to Test Explorer and click Run All. After running Tests, you will see the
output, as given below.
Both Test Method Test_AddMethod and Test_MultiplyMethod failed. To know why these methods
failed while testing, click each method and read the reason.
In Test_AddMethod Assert.AreEqual is supposed to give 41 as an actual value but we are
expecting 21. It must be 41 to get Test passed. Of course after adding 20.50 and 20.50, we will
get 41. Thus, we have written the wrong expected value. Change it to 41 instead of 21.
189
In Test_MultiplyMethod Assert.AreEqual is supposed to give 20 but we are expecting 100. It must
be 20 to get the test passed but logically after multiplying 10 and 10, we should get 100, then why
its actual value is returning 20. Check the code of Multiply method in BasicMaths class.
As we can see we are using +(Plus) operator between two operands- num1 and num2 which
should be *(Multiply) operator. Now, the given code is a logically correct one.
1. public double Multiply(double num1, double num2)
2. {
3.
return num1 * num2;
4. }
190
After correcting wrong values and codes, let's run the test again and see the result. Both Test
methods Test_AddMethod and Test_MultiplyMethod are passed.
Course Materials
https://www.softwaretestinghelp.com/difference-between-test-plan-test-strategy-test-case-testscript-test-scenario-and-test-condition/
https://www.c-sharpcorner.com/article/a-basic-introduction-of-unit-test-for-beginners/
Activities and Assessments
Using the application created in Module 5, create a Unit Test Project and implement testing
scenarios for that application. Make sure to implement the following test results:
• True Positive
• True Negative
• False Positive
• False Negative
191
192
Download