You are on page 1of 65

Page 1 of 65

Bangladesh Institute of Management


4 Sobhanbag, Mirpur Road, Dhaka-1207

POST-GRADUATE DIPLOMA IN COMPUTER SCIENCE


SUBJECT: Database Management System-II (Software Development)
FULL MARKS: 100

Chapter Topic

01. Introduction to Client-Server Application Development


02. Principles of Interface Designing
03. Introduction to Visual Tools
04. Using labels, Buttons, Text boxes
05. Variables, Controls and Operators
06. Looping Arrays and Lists
07. Functions
08. Debugging in Visual Tools
09. File Controls
10. API
11. Database
12. Programming
13. Application Development
14. Case Study
Course Materials Reference:
1. http://msdn.microsoft.com
2. http://www.w3.org/TR/html5
3. http://www.w3schools.com
4. http://www.jquery.com
5. https://angularjs.org
6. https://www.javascript.com

Page 2 of 65

01. Introduction to Client-Server Application Development


What is a client-server application?
Client-server describes an application architecture in which the client requests
an action or service from the provider of service, the server. Consider a Web
browser and a Web server. When you address a URL in the browser window, it
(client) requests a page from a Web server. The server returns an html page
to the client, which parses the page (data) and displays it on your computer.
When developing a client-server application, like the Web browser and Web
server, you need to consider how you are going to handle developing your
application in a team environment and how you are going to handle long-term
maintenance. In a client-server application, a module does not have to be part
of the same program or even run on the same computer. Each modular
function can run on a different device.
How does a client perform?
Client programs request service from a server by sending it a message.
Referring back to the Web example, a Web browser is a client we use every
day to request Web pages. For example, when you clicked the link to read this
article, your browser sent a message to a Web server. In response, your
browser received the html page you are now reading. A Web browser
represents many client programs, which manage the graphical user interface
(GUI) or display portion of an application; determining the presentation of the
service provided by an application.
What is a server's function?
Server programs process client requests by performing the tasks requested by
clients. For example, in a Web browser the Web server returns the html page
requested by the client. But client requests and server programs are not
always so simple. Servers are generally passive as they wait for a client
request. During these waiting periods servers can perform other tasks or
perform maintenance. Unlike the client, the server must continually run
because clients can request service at any time. Clients on the other hand

Page 3 of 65

only need to run when they require service. Many server applications allow for
multiple clients to request service. For example, while you are reading this
page others interested in client-server programming could also request and
read the same Web page.
Features of a client/server application:

A client program can request services from multiple server programs

A client program does not need to be aware of the actual subprograms


that provide a service

Multiple client programs can request services from a single server


program

A server program can provide multiple services

Client/Server Benefits:
Most of the benefits of using client/server architecture for enterprise
applications

relate to

flexibility

of

deployment

and

relative ease

of

maintenance.

Re-use existing legacy code for the business logic


Distribute the processing and network loads
Quickly and easily change business logic procedures without changing
the client program or user interface
Provide alternative client user interfaces to the same server-side
program.

Page 4 of 65

Page 5 of 65

02. Principles of Interface Designing


Lets start with the fundamentals of user interface design. These principles
are
1.

The structure principle. Your design should organize the user


interface purposefully, in meaningful and useful ways based on clear,
consistent models that are apparent and recognizable to users, putting
related things together and separating unrelated things, differentiating
dissimilar things and making similar things resemble one another. The
structure principle is concerned with your overall user interface
architecture.

2.

3.

4.

The simplicity principle. Your design should make simple, common


tasks simple to do, communicating clearly and simply in the users own
language, and providing good shortcuts that are meaningfully related
to longer procedures.

Page 6 of 65

5.

The visibility principle. Your design should keep all needed options
and materials for a given task visible without distracting the user with
extraneous or redundant information. Good designs dont overwhelm
users with too many alternatives or confuse them with unneeded
information.

6.

7.

The feedback principle. Your design should keep users informed of


actions or interpretations, changes of state or condition, and errors or
exceptions that are relevant and of interest to the user through clear,
concise, and unambiguous language familiar to users.

8.

5. The tolerance principle. Your design should be flexible and tolerant,


reducing the cost of mistakes and misuse by allowing undoing and
redoing, while also preventing errors wherever possible by tolerating
varied inputs and sequences and by interpreting all reasonable actions
reasonable.
6. The reuse principle. Your design should reuse internal and external
components and behaviors, maintaining consistency with purpose
rather than merely arbitrary consistency, thus reducing the need for
users to rethink and remember.

Tips and Techniques


The following tips and techniques that I have learned over the years should prove
valuable:

1.

Consistency, consistency, consistency. I believe the most


important thing you can possibly do is ensure your user interface
works consistently. If you can double-click on items in one list and have
something happen, then you should be able to double-click on items in
any other list and have the same sort of thing happen. Put your
buttons in consistent places on all your windows, use the same
wording in labels and messages, and use a consistent color scheme
throughout. Consistency in your user interface enables your users to
build an accurate mental model of the way it works, and accurate
mental models lead to lower training and support costs.

Page 7 of 65

2.

Set standards and stick to them. The only way you can ensure
consistency within your application is to set user interface design
standards, and then stick to them. You should follow Agile Modeling
(AM)s Apply Modeling Standards practice in all aspects of software
development, including user interface design.

3.

Be prepared to hold the line. When you are developing the user
interface for your system you will discover that your stakeholders often
have some unusual ideas as to how the user interface should be
developed. You should definitely listen to these ideas but you also
need to make your stakeholders aware of your corporate UI standards
and the need to conform to them.

4.

Explain the rules. Your users need to know how to work with the
application you built for them. When an application works consistently,
it means you only have to explain the rules once. This is a lot easier
than explaining in detail exactly how to use each feature in an
application step-by-step.

5.

Navigation between major user interface items is important. If


it is difficult to get from one screen to another, then your users will
quickly become frustrated and give up. When the flow between
screens matches the flow of the work the user is trying to accomplish,
then your application will make sense to your users. Because different
users work in different ways, your system needs to be flexible enough
to support their various approaches. User interface-flow diagrams
should optionally be developed to further your understanding of the
flow of your user interface.

6.

Navigation within a screen is important. In Western societies,


people read left to right and top to bottom. Because people are used to
this, should you design screens that are also organized left to right and
top to bottom when designing a user interface for people from this
culture? You want to organize navigation between widgets on your
screen in a manner users will find familiar to them.

7.

Word your messages and labels effectively. The text you display
on your screens is a primary source of information for your users. If
your text is worded poorly, then your interface will be perceived poorly
by your users. Using full words and sentences, as opposed to
abbreviations and codes, makes your text easier to understand. Your
messages should be worded positively, imply that the user is in
control, and provide insight into how to use the application properly.

Page 8 of 65

For example, which message do you find more appealing You have
input the wrong information or An account number should be eight
digits in length. Furthermore, your messages should be worded
consistently and displayed in a consistent place on the screen.
Although the messages The persons first name must be input and
An account number should be input are separately worded well,
together they are inconsistent. In light of the first message, a better
wording of the second message would be The account number must
be input to make the two messages consistent.
8.

Understand the UI widgets. You should use the right widget for the
right task, helping to increase the consistency in your application and
probably making it easier to build the application in the first place. The
only way you can learn how to use widgets properly is to read and
understand the user-interface standards and guidelines your
organization has adopted.

9.

Look at other applications with a grain of salt. Unless you know


another application has been verified to follow the user interfacestandards and guidelines of your organization, dont assume the
application is doing things right. Although looking at the work of others
to get ideas is always a good idea, until you know how to distinguish
between good user interface design and bad user interface design, you
must be careful. Too many developers make the mistake of imitating
the user interface of poorly designed software.

10. Use color appropriately. Color should be used sparingly in your


applications and, if you do use it, you must also use a secondary
indicator. The problem is that some of your users may be color blind
and if you are using color to highlight something on a screen, then you
need to do something else to make it stand out if you want these
people to notice it. You also want to use colors in your application
consistently, so you have a common look and feel throughout your
application.
11. Follow the contrast rule. If you are going to use color in your
application, you need to ensure that your screens are still readable.
The best way to do this is to follow the contrast rule: Use dark text on
light backgrounds and light text on dark backgrounds. Reading blue
text on a white background is easy, but reading blue text on a red
background is difficult. The problem is not enough contrast exists
between blue and red to make it easy to read, whereas there is a lot of
contrast between blue and white.

Page 9 of 65

12. Align fields effectively. When a screen has more than one editing
field, you want to organize the fields in a way that is both visually
appealing and efficient. I have always found the best way to do so is to
left-justify edit fields: in other words, make the left-hand side of each
edit field line up in a straight line, one over the other. The
corresponding labels should be right-justified and placed immediately
beside the field. This is a clean and efficient way to organize the fields
on a screen.
13. Expect your users to make mistakes. How many times have you
accidentally deleted some text in one of your files or deleted the file
itself? Were you able to recover from these mistakes or were you
forced to redo hours, or even days, of work? The reality is that to err is
human, so you should design your user interface to recover from
mistakes made by your users.
14. Justify data appropriately. For columns of data, common practice
is to right-justify integers, decimal align floating-point numbers, and to
left-justify strings.
15. Your design should be inimitable. In other words, if your users
dont know how to use your software, they should be able to determine
how to use it by making educated guesses. Even when the guesses are
wrong, your system should provide reasonable results from which your
users can readily understand and ideally learn
16. Dont create busy user interfaces. Crowded screens are difficult to
understand and, hence, are difficult to use. Experimental results show
that the overall density of the screen should not exceed 40 percent,
whereas local density within groupings should not exceed 62 percent.

03. Introduction to Visual Tools


04. Using labels, Buttons, Text boxes
Windows Form Controls
WindowsForm: As forms are the base unit of your application, it is essential
that you give some thought to their function and design. A form is ultimately

Page 10 of 65

a blank slate that you, as a developer, enhance with controls to create a user
interface and with code to manipulate data. To that end, Visual Studio
provides you with an integrated development environment (IDE) to aid in
writing code, as well as a rich control set written with the .NET Framework. By
complementing the functionality of these controls with your code, you can
easily and quickly develop the solutions you need.
Button : The Button control presents a standard command button, which is
rendered as an HTML input element. Using a Button control on ASP.NET web
pages allows users to indicate that they have completed the form or that they
want to perform a specific command. Web server controls include three kinds
of buttons, each of which appears differently on web pages: Button controls,
LinkButton control controls, and ImageButton control controls.
When a user clicks any of the three types of buttons, a form is submitted to
the server. This causes the web page to be processed and any pending events
to be raised in server-based code.
Label: Label controls usually provide information in the user interface (UI).
Historically, a Label has contained only text, but because the Label that ships
with Windows Presentation Foundation (WPF) is a ContentControl, it can
contain either text or a UIElement.
A Label provides both functional and visual support for access keys. It is
frequently used to enable quick keyboard access to controls such as a
TextBox. To assign a Label to a Control, set the Label.Target property to the
control that should get focus when the user presses the access key.
TextBox: Windows Forms text boxes are used to get input from the user or to
display text. The TextBox control is generally used for editable text, although
it can also be made read-only. Text boxes can display multiple lines, wrap text
to the size of the control, and add basic formatting. The TextBox control
allows a single format for text displayed or entered in the control.
ListBox: Defines commonly used controls for a dialog box or window. The
control is a rectangle containing a list of strings (such as filenames) from
which the user can select.
The LISTBOX statement, which can only be used in a WINDOW statement,
defines the identifier, dimensions, and attributes of a control window.
CheckBox: This CheckBox_control is a two-state check box. To associate an
integer or string property with this control, enter the property name into the
Property column of the Control table. The selected state of the box sets the
property either to the value specified in the Value column of the CheckBox
table or to the initial value of the property specified in the Property table. If
the property has no initial value, the checked state sets it to 1. The
unselected state sets the property to null.

Page 11 of 65

CheckBox controls can only be used to publish AddLocal ControlEvent,


AddSource ControlEvent, Remove ControlEvent, DoAction ControlEvent, or
SetProperty ControlEvent controls.

LinkLabel: The Windows Forms LinkLabel control allows you to add Webstyle links to Windows Forms applications. You can use the LinkLabel control
for everything that you can use the Label control for; you also can set part of
the text as a link to an object or Web page.
RadioButton:
You can use two types of ASP.NET controls to add radio
buttons to a page: individual RadioButton controls or a RadioButtonList
control. Both controls allow users to select from a small set of mutually
exclusive, predefined choices. The controls allow you to define any number of
radio buttons with labels and to arrange them horizontally or vertically. For a
comparison of RadioButton and RadioButtonList controls, see RadioButtonList
control.
To add a RadioButton control to a page
1. Drag the RadioButton control from the Toolbox task pane to your page.
2. Set properties for the control in the Tag Properties task pane.
DataGridView: The DataGridView control provides a powerful and flexible
way to display data in a tabular format. You can use the DataGridView control
to show read-only views of a small amount of data, or you can scale it to show
editable views of very large sets of data.
You can extend the DataGridView control in a number of ways to build custom
behaviors into your applications. For example, you can programmatically
specify your own sorting algorithms, and you can create your own types of
cells. You can easily customize the appearance of the DataGridView control by
choosing among several properties. Many types of data stores can be used as
a data source, or the DataGridView control can operate with no data source
bound to it.

MenuStrip: Menus expose functionality to your users by holding commands


that are grouped by a common theme. The MenuStrip control is new to this
version of Visual Studio and the .NET Framework. With the control, you can
easily create menus like those found in Microsoft Office.The MenuStrip control
supports the multiple-document interface (MDI) and menu merging, tool tips,
and overflow. You can enhance the usability and readability of your menus by
adding access keys, shortcut keys, check marks, images, and separator bars.
FileSystemWatcher: The FileSystemWatcher control is an extension of the
System.IO namespace that allows the Windows operating system to notify
application of any file changes that have occurred.

Page 12 of 65

DateTimePicker: The DateTimePicker control displays date and/or time


information and acts as the interface through which users can modify date
and time information. The control's display consists of fields that are defined
by the control's format string. When the DateTimePicker is dropped down, a
MonthView calendar is displayed.
The control has two different modes:
Dropdown Calendar mode (default) enables the user to display a dropdown
calendar that can be used to select a date.
Time Format mode enables the user to select a field in the date display (i.e.
the month, day, year, etc.) and press the up/down arrow to the right of the
control to set its value.
You can use the control to display the date in various preset formats including
Short Date (11/14/97), LongDate (Friday, November 14, 1997) and Time
(7:00:00 PM). You can also specify custom formats using formatting strings, or
create your own formats.

TreeView: A tree-view control is a window that displays a hierarchical list of


items, such as the headings in a document, the entries in an index, or the files
and directories on a disk. Each item consists of a label and an optional
bitmapped image, and each item can have a list of subitems associated with
it. By clicking an item, the user can expand or collapse the associated list of
subitems.
The following illustration shows a simple tree-view control with a root node, an
expanded node, and a collapsed node. The control uses one bitmap for the
selected item and another bitmap for other items.
After creating a tree-view control, you add, remove, arrange, or otherwise
manipulate items by sending messages to the control. Each message has one
or more corresponding macros that you can use instead of sending the
message explicitly.
GroupBox: The GroupBox control displays a rectangle, possibly with caption
text, that serves to group other controls together on the dialog box.
ComboBox: The ComboBox control displays a drop-down list of predefined
values and an edit field into which the user can enter a value. To associate
this control with a string or integer property, enter the property's name in the
Property column of the Control table.

ASP.NET Web Controls


WebForms:
Web Forms are pages that your users request using their
browser. These pages can be written using a combination of HTML, clientscript, server controls, and server code. When users request a page, it is

Page 13 of 65

compiled and executed on the server by the framework, and then the
framework generates the HTML markup that the browser can render. An
ASP.NET Web Forms page presents information to the user in any browser or
client device.
LinkButton: The LinkButton control renders as a hyperlink in the page.
However, it contains client-side script that causes the form to be posted back
to the server.
To add a LinkButton control to a page
1. Drag the LinkButton control from the Toolbox task pane to your page.
2. Set properties for the control in the Tag Properties task pane.

CheckBoxList: The CheckBoxList control is a single control that acts as a


parent control for a collection of check-box list items. It derives from a base
ListControl class, and therefore works much like the ListBox control,
DropDownList control, RadioButtonList control, and BulletedList control
controls. For that reason, many of the procedures for working with the
CheckBoxList control are the same as the procedures for the other list web
server controls.
Each type of control has advantages. By using individual CheckBox controls,
you get more control over the layout of the check boxes on the page than by
using the CheckBoxList control. For example, you can include text (that is,
non-check-box text) between each check box. You can also control the font
and color of individual check boxes. The CheckBoxList control is a better
choice if you want to create a series of check boxes from data in a database.
RadioButtonList: The RadioButtonList control is a single control that acts as
a parent control for a collection of radio button list items. The RadioButtonList
control does not permit you to insert text between the buttons, but is far
easier to use if you want to bind the buttons to a data source. It is also slightly
easier to write code that determines which button has been selected.The
RadioButtonList control raises a SelectedIndexChanged event when users
change which radio button in the list is selected.
HyperLink: The HyperLink control creates links on a web page that allow
users to move from page to page in your application. The HyperLink control
can display clickable text or an image. Unlike most ASP.NET controls, the
HyperLink control does not raise an event in server code when users click it.
Instead, the control simply performs navigation.
The primary advantage of using a HyperLink control is that you can set link
properties in server code. For example, you can dynamically change the link
text or target page based on conditions in your page.Another advantage of
using the HyperLink control is that you can use data binding to specify the
target URL for the link (and parameters to be passed with the link, if

Page 14 of 65

necessary). A typical example is to create HyperLink controls based on a list


of products; the target URL points to a page where the user can read more
detail about the product.

Panel: The Panel control provides a grouping mechanism for organizing


controls. Panel controls can be recursively nested within a Form control the
Panel control's outermost container. A panel renders the controls contained
inside itself.Style attributes that are set on a panel can be inherited by other
controls contained in that same panel.
Image: The Image control allows you to display images on an ASP.NET web
page and manage these images in your own code.
You can specify the graphics file for an Image control at design time or at run
time programmatically. You can also bind the control's ImageUrl property to a
data source to display graphics based on database information.Unlike most
other ASP.NET controls, the Image control does not support any events. For
example, the Image control does not respond to mouse clicks. Instead, you
can create an interactive image by using the ImageMap or the ImageButton
ASP.NET controls.
ImageButton: An ImageButton control allows you to present a picture as a
clickable control. When users click an ImageButton control, a parameter
passed to the event handler for the control's Click event includes the
coordinates indicating where the user clicked. This allows you to perform
different tasks based on where the user clicked. Coordinate information is
sent as part of the event-argument object for the ImageButton control's Click
event.
DropDownList: The DropDownList web server control enables users to select
an item from a predefined list. It differs from the ListBox web server control in
that the list of items remains hidden until users click the drop-down button. In
addition, the DropDownList control differs from the ListBox control because it
does not support multi-selection mode.

N.B: Similar type of controls description given in above section.

Page 15 of 65

ASP.NET - Data Controls

DataList: The DataList control displays data in a format that you can define
using templates and styles. Its useful for data in any repeating structure,
such as a table. The DataList control can display rows in different layouts,
such as ordering them in columns or rows.
GridView: A recurring task in software development is to display tabular
data. ASP.NET provides a number of tools for showing tabular data in a grid,
including the GridView control. With the GridView control, you can display,
edit, and delete data from many different kinds of data sources, including
databases, XML files, and business objects that expose data.
The GridView control displays data in read-only
also supports an edit mode in which it displays
controls such as TextBoxor CheckBoxcontrols.
GridView control to display a Delete button that
corresponding record from the data source.

mode. However, the control


a row that contains editable
You can also configure the
users can click to delete the

The GridView control can automatically perform editing and deleting


operations with its associated data source, which allows you to enable editing
behavior without writing code. Alternatively, you can control the process of
editing and deleting data programmatically, such as in cases where the
GridView control is bound to a read-only data source control.

ListView: The ListView control displays items using one of four different
views. You can arrange items into columns with or without column headings
as well as display accompanying icons and text. The View property
determines which view the control uses to display the items in the list. You
can also control whether the labels associated with items in the list wrap to
more than one line using the LabelWrap property. In addition, you can
manage how items in the list are sorted and how selected items appear.

SqlDataSource: The SqlDataSource control enables you to use a Web server


control to access data that is located in a relational database. This can include
Microsoft SQL Server and Oracle databases, as well as OLE DB and ODBC data
sources. You can use the SqlDataSource control with data-bound controls such
as the GridView, FormView, and DetailsView controls to display and
manipulate data on an ASP.NET Web page, using little or no code.

Page 16 of 65

Windows Forms Controls


1. WindowsFor
m
2. Button
3. Label
4. TextBox

5. ListBox
6. CheckBox
7. LinkLabel
8. RadioButto
n

9. DataGridView
10. MenuStrip
11. FileSystemWatch
er
12. DateTimePicker

13. TreeView
14. GroupBox
15. ComboBox

1. WindowsForm: A form is ultimately a blank slate that you, as a developer,


enhance with controls to create a user interface and with code to manipulate
data.
2. Button: Raises an event when user clicked on it.
3. Label: Provides Runtime information for a control.
4. TextBox: Enable the user to enter text, and provides multiline editing and
password character masking.
5. ListBox: Displays a list which the user can select items.
6. CheckBox: Enables the user to select or clear associated option.
7. LinkLabel: Displays a label control that support hyperlink functionality, formatting
and tracking.
8. RadioButton: Enable user to select a single option from a group of choices when
paired with other radiobuttons.
9. DataGridView: Displays rows and columns in a grid you can customize.
10. MenuStrip: Displays application commands and options group by functionality.
11. FileSystemWatcher: Monitors file system change notifications and raises when a
dictionary or file changes.
12. DateTimePicker: Enable the user to select date and time in a specific format.
13. TreeView: Displays a hierarchical collection of labeled to the user that optionally
contain image
14. GroupBox: Displays a frame with around a group of controls with an optinal
captions.
15. ComboBox: Displays an editable textbox with a drop down list of permitted values.

ASP.NET - Data Controls


1. DataList

2. GridView

3. ListView

4. SqlDataSource

1. DataList: The DataList control displays data in a format that you can define using
templates and styles.
2. GridView: With the GridView control, you can display, edit, and delete data from
many different kinds of data sources, including databases, XML files, and business
objects that expose data.
3. ListView: The ListView control is useful for displaying data in any repeating
structure, similar to the DataList.
4. SqlDataSource: The SqlDataSource control enables you to use a web control to
access data located in a relational data base.

Page 17 of 65

ASP.NET Web Controls


1. WebForms
2. Button
3. Label
4. TextBox

5. CheckBox
6. CheckBoxList
7. RadioButton
8. RadioButtonList

9. HyperLink
10. ListBox
11. Panel
12. Image

13. ImageButton
14. DropDownList
15. LinkButton

1. WebForms: Web Forms are pages that your users request using their browser.
These pages can be written using a combination of HTML, client-script, server
controls, and server code.
2. LinkButton: The LinkButton control is used to create a hyperlink button.
3. CheckBoxList: The CheckBoxList control is used to create a multi-selection check
box group.
4. RadioButtonList: Control is used to create a group of radio buttons.
5. HyperLink: Control is used to create a hyperlink.
6. Panel: Provides a container for other controls.
7. Image: Displays an image.
8. ImageButton: Displays a clickable image.
9. DropDownList: The DropDownList control is used to create a drop-down list. Each
selectable item in a DropDownList control is defined by a ListItem element.
N.B.:Similar type of controls description given in above section.

ASP.NET - HTML Server Controls


1. Input(Button
)
2. Input(Text)

3. Input(File)
4. Input(CheckBo
x)

5. Input(Radio)
6. Table

7. Select
8. Image

1. Input(Button): InputButton control is used to control <input type="button">,


<input type="submit">, and <input type="reset"> elements. These elements are
used to create a command button, a submit button, and a reset button.
2. Input(Text): These elements are used to create a text field and a password field.
3. Input(File): This element is used to upload a file to the server.
4. Input(CheckBox): The InputCheckBox control is used to control an <input
type="checkbox"> element. In HTML, this element is used to create a checkbox.
5. Input(RadioButton):
InputRadioButton control is used to control an <input
type="radio"> element. In HTML, this element is used to create a radiobutton.
6. Table: The Table control is used to control a <table> element. In HTML, the
<table> element is used to create a table.
7. Select: The Select control is used to control a <select> element. In HTML, the
<select> element is used to create a drop-down list.
8. Image: The Image control is used to control an <img> element. In HTML, the
<img> element is used to display an image.

Sources: http://www.w3schools.com, http://msdn.microsoft.com

Page 18 of 65

DATABASE DEVELOPMENT:
Database Name: BIM2015DB
Tables:
1. PUBSINF - Consists records for publishers general
information
2. TITLES - Consists records for books general information
Table Structure: PUBSINF
Column Name
pub_id
pub_name
pr_info

Data Type
char(4)
nvarchar(100)
text

Allow
Null

Descriptions
Publisher ID (Primary Key)
Publisher Name
Publisher details description

Table Structure: TITLES


Column Name
title_id
title
ptype

Data Type
varchar(6)
varchar(80)
char(12)

pub_id
price
pubdate

char(4)
decimal(18, 6)
datetime

Allow
Null

Descriptions
Book ID (Primary Key)
Title of the book
Book type
Publisher ID (Foreign Key from
PUBSINF)
Sales Price of the book
Publishing Date

Records: PUBSINF
pub_id

pub_name

0736
0877

Binnet & Hardley

1389
1622
1756
9901
9952
9999

Algodata Infosystems
Five Lakes Publishing
Ramona Publishers
GGG&G, publisher
Scootney Books
Lucerne publishing

pr_info
New Moon Books is located in Boston, Massachusetts.
Binnet & Hardley is located in Washington, D.C.
Algodata Infosystems is located in Berkeley,
California.
Five Lakes Publishing is located in Chicago, Illinois.
Ramona Publishers is located in Dallas, Texas.
GGG&G is located in Mnchen, Germany.
Scootney Books is located in New York City, New York.
Lucerne publishing is located in Paris, France.

Page 19 of 65

Records: TITLES
title_i
d
BU103
2
BU111
1
BU207
5
BU783
2
MC22
22
MC30
21
MC30
26
PC103
5
PC665
5
PC665
6
PC666
6
PC888
8
PC999
9
PS137
2
PS209
1
PS333
3
TC321
8
TC420
3
TC777
7

ptype

Pub_i
d

price

The Busy Executive's Database


Guide
Cooking with Computers:
Surreptitious Balance Sheets
You Can Combat Computer
Stress!
Straight Talk About Computers

business

1389

19.99

business

1389

11.95

business

0736

2.99

business

1389

19.99

Silicon Valley Gastronomic


Treats
The Gourmet Microwave

mod_cook

0877

19.99

mod_cook

0877

2.99

The Psychology of Computer


Cooking
But Is It User Friendly?

UNDECIDED

0877

NULL

popular_com
p
popular_com
p
popular_com
p
popular_com
p
popular_com
p
popular_com
p
psychology

1389

22.95

1389

25.00

1389

55.00

1389

25.00

1389

20.00

1389

NULL

0877

21.59

psychology

0736

10.95

psychology

0736

19.99

trad_cook

0877

20.95

trad_cook

0877

11.95

trad_cook

0877

14.99

title

Secrets of Silicon Valley - 3


Secrets of Silicon Valley - 4
Secrets of Silicon Valley - 2
Secrets of Silicon Valley
Net Etiquette
Computer Phobic AND NonPhobic Individuals: Behavior
Variations
Is Anger the Enemy?
Prolonged Data Deprivation:
Four Case Studies
Onions, Leeks, and Garlic:
Cooking Secrets of the
Mediterranean
Fifty Years in Buckingham
Palace Kitchens
Sushi, Anyone?

Pubdate
1991-06-12
00:00:00
1991-06-09
00:00:00
1991-06-30
00:00:00
1991-06-22
00:00:00
1991-06-09
00:00:00
1991-06-18
12:00:00
2004-12-13
16:11:36
1991-06-30
12:40:00
2005-06-12
12:45:00
2008-06-12
12:45:00
2001-06-12
00:00:00
1994-06-12
00:00:00
2004-12-13
16:11:36
1991-10-21
00:00:00
1991-06-15
00:00:00
1991-06-12
00:00:00
1991-10-21
00:00:00
1991-06-12
00:00:00
1995-06-12
12:40:00

Page 20 of 65

Book Information Records Entry/ Display Screen: (for TITLES table)

Page 21 of 65

Page 22 of 65

.Net Framework Library Used


For Windows Application
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

For Web Application


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;

From System.Data.SqlClient;

Page 23 of 65

SqlConnection
SqlCommand
SqlDataAdapter
SqlConnection SCon1 = new SqlConnection("Data Source=ASIT-03\\SQL2K5EXP;
Initial Catalog=BIM2015DB;Integrated Security=True");

From System.Data;
DataSet
DataTable

Page 24 of 65
using
using
using
using
using
using
using
using
using

System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;
System.Data.SqlClient;

namespace BIMWINAPP
{
public partial class Form1 : Form
{
SqlConnection SCon1 = new SqlConnection("Data Source=ASIT-03\\SQL2K5EXP;
Initial Catalog=BIM2015DB;Integrated Security=True");
DataTable tblTitle, tblPubs;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void btnShow_Click(object sender, EventArgs e)
{
string SqlStatment1 = "";
//SqlStatment1 = "select * from titles";
SqlStatment1 = "select title_id, title, ptype, pub_id, ";
SqlStatment1 += "price = isnull(price, 0.00), pubdate from titles;";
SqlStatment1 += "select pub_id, pub_name from pubsinf;";
SqlCommand SCmd1 = new SqlCommand();
SCmd1.CommandText = SqlStatment1;

SCmd1.Connection = SCon1;
DataSet ds1 = new DataSet();
SqlDataAdapter SDap1 = new SqlDataAdapter(SCmd1);
SDap1.Fill(ds1);
tblTitle = ds1.Tables[0];
tblPubs = ds1.Tables[1];
this.dgv1.AutoGenerateColumns = false;
this.dgv1.DataSource = tblTitle;
this.groupBox1.Enabled = true;

private void btnExit_Click(object sender, EventArgs e)


{
this.Close();
}
private void dgv1_RowEnter(object sender, DataGridViewCellEventArgs e)
{
if (dgv1.RowCount<= 0)
return;
this.ShowRecord(e.RowIndex);
}

Page 25 of 65

private void ShowRecord(int RecNo)


{
this.lbl_RecNo.Text = "Record No: " + (RecNo + 1).ToString()
+ " of " + tblTitle.Rows.Count.ToString();
this.txt_title_id.Text = tblTitle.Rows[RecNo]["title_id"].ToString();
this.txt_title.Text = tblTitle.Rows[RecNo]["title"].ToString();
this.txt_ptype.Text = tblTitle.Rows[RecNo]["ptype"].ToString();
//this.txt_pub_id.Text = tblTitle.Rows[RecNo]["pub_id"].ToString();
this.txt_price.Text =
Convert.ToDouble(tblTitle.Rows[RecNo]["price"]).ToString("#,##0.00");
this.txt_pubdate.Text =
Convert.ToDateTime(tblTitle.Rows[RecNo]["pubdate"]).ToString("dd-MMM-yyyy hh:mm:ss tt");
string pubID1 = tblTitle.Rows[RecNo]["pub_id"].ToString().Trim();
DataRow[] drow1 = tblPubs.Select("pub_id='" + pubID1 + "'");
string pubName1 = drow1[0]["pub_name"].ToString().Trim();
this.txt_pub_id.Text = pubID1 + " - " + pubName1;
}
private void btnTop_Click(object sender, EventArgs e)
{
this.dgv1.CurrentCell = this.dgv1[1, 0];
this.ShowRecord(0);
}
private void btnBottom_Click(object sender, EventArgs e)
{
int i = this.dgv1.Rows.Count - 1;
this.dgv1.CurrentCell = this.dgv1[1, i];
this.ShowRecord(i);
}
private void btnPrev_Click(object sender, EventArgs e)
{
int i = this.dgv1.CurrentRow.Index -1 ;
if (i < 0)
i = this.dgv1.Rows.Count - 1;

this.dgv1.CurrentCell = this.dgv1[1, i];


this.ShowRecord(i);

private void btnNext_Click(object sender, EventArgs e)


{
int i = this.dgv1.CurrentRow.Index + 1;
if (i == this.dgv1.Rows.Count)
i = 0;

this.dgv1.CurrentCell = this.dgv1[1, i];


this.ShowRecord(i);

Page 26 of 65
private void btnInsert_Click(object sender, EventArgs e)
{
string _insertID = this.txt_title_id.Text.Trim();
DataRow[] dr1 = tblTitle.Select("title_id = '" + _insertID + "'");
if (dr1.Length > 0)
{
MessageBox.Show("titel_id " + _insertID + " already exist",
"Record Insert Not Possible", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
string _titleDes = this.txt_title.Text.Trim();
string _tptype = this.txt_ptype.Text.Trim();
string _pubid = this.txt_pub_id.Text.Trim().Substring(0, 4);
string _sprice = "0" + this.txt_price.Text.Trim().Replace(",", "");
string _pudate = this.txt_pubdate.Text.Trim();
if (MessageBox.Show("Are you sure to Insert record for ID = "
+ _insertID, "Confirmation", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
// title, ptype, pub_id, price = isnull(price, 0.00), pubdate
string SqlStatment1 = "insert into titles (title_id, title, ptype, pub_id, ";
SqlStatment1 += "price, pubdate) values ('" + _insertID + "', '" + _titleDes;
SqlStatment1 += "', '" + _tptype + "', '" + _pubid + "', ";
SqlStatment1 += _sprice + ", '" + _pudate + "')";
SqlCommand SCmd1 = new SqlCommand();
SCmd1.CommandText = SqlStatment1;
SCmd1.Connection = SCon1;
SCon1.Open();
int _result = SCmd1.ExecuteNonQuery();
SCon1.Close();
if (_result < 0)
{
MessageBox.Show("Record not inserted");
return;
}
this.btnShow_Click(null, null);
int RecNo = 0;
for (int i = 0; i < tblTitle.Rows.Count; i++)
{
if (tblTitle.Rows[i]["title_id"].ToString().Trim() == _insertID)
{
RecNo = i;
break;
}
}
this.dgv1.CurrentCell = this.dgv1[1, RecNo];
this.ShowRecord(RecNo);
}

Page 27 of 65
private void btnUpdate_Click(object sender, EventArgs e)
{
int RecNo = this.dgv1.CurrentRow.Index;
string _updateID = this.txt_title_id.Text.Trim();
string _titleDes = this.txt_title.Text.Trim();
string _tptype = this.txt_ptype.Text.Trim();
string _pubid = this.txt_pub_id.Text.Trim().Substring(0, 4);
string _sprice = "0"+ this.txt_price.Text.Trim().Replace(",", "");
string _pudate = this.txt_pubdate.Text.Trim();

if (MessageBox.Show("Are you sure to update record for ID = "


+ _updateID, "Confirmation", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
// title, ptype, pub_id, price = isnull(price, 0.00), pubdate
string SqlStatment1 = "update titles set title = '" + _titleDes ;
SqlStatment1 += "', ptype = '" + _tptype + "', pub_id = '" + _pubid;
SqlStatment1 + = "', price = " + _sprice + ", pubdate = '" + _pudate + "'";
SqlStatment1 + = " where title_id = '" + _updateID + "'";
SqlCommand SCmd1 = new SqlCommand();
SCmd1.CommandText = SqlStatment1;
SCmd1.Connection = SCon1;
SCon1.Open();
int _result = SCmd1.ExecuteNonQuery();
SCon1.Close();
if (_result < 0)
{
MessageBox.Show("Record not updated");
return;
}
this.btnShow_Click(null, null);
this.dgv1.CurrentCell = this.dgv1[1, RecNo];
this.ShowRecord(RecNo);

private void btnDelete_Click(object sender, EventArgs e)


{
string _delID = this.txt_title_id.Text.Trim();
if (MessageBox.Show("Are you sure to delete record for ID = "
+ _delID, "Confirmation", MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
string SqlStatment1 = "delete from titles where title_id = '" + _delID + "'";
SqlCommand SCmd1 = new SqlCommand();
SCmd1.CommandText = SqlStatment1;
SCmd1.Connection = SCon1;
SCon1.Open();
int _result = SCmd1.ExecuteNonQuery();
SCon1.Close();
if (_result < 0)
{
MessageBox.Show("Record not deleted");
return;
}
this.btnShow_Click(null, null);
}

Page 28 of 65

private void btnClear_Click(object sender, EventArgs e)


{
this.lbl_RecNo.Text = "No Record";
this.txt_title_id.Text = "";
this.txt_title.Text = "";
this.txt_ptype.Text = "";
this.txt_pub_id.Text = "";
this.txt_price.Text = "";
this.txt_pubdate.Text = "";

}
}

this.groupBox1.Enabled = false;
this.dgv1.DataSource = null;

Page 29 of 65

05. Variables, Controls and Operators

Variables are used to store values. More technically, a variable binds an object (in the general sense
of the term, i.e. a specific value) to an identifier (the variable's name) so that the object can be
accessed later. Variables can, for example, store a value for later use:

string name = "Dr. Jones";


Console.WriteLine("Good morning " + name);

Fields, local variables, and parameters


C# supports several program elements corresponding to the general programming concept
of variable: fields, parameters, and local variables.

Fields
Fields, sometimes called class-level variables, are variables associated with classes or structures.
An instance variable is a field associated with an instance of the class or structure, while a static
variable, declared with the static keyword, is a field associated with the type itself. Fields can also be
associated with their class by making them constants (const), which requires a declaration
assignment of a constant value and prevents subsequent changes to the field.
Each field has a visibility of public, protected, internal, protected internal, or private (from most visible
to least visible).

Local variables
Like fields, local variables can optionally be constant (const). Constant local variables are stored in
the assembly data region, while non-constant local variables are stored on (or referenced from) the
stack. They thus have both a scope and an extent of the method or statement block that declares
them.

Parameter
Parameters are variables associated with a method.

The built-in C# type aliases and their equivalent .NET Framework types follow:

Page 30 of 65
Integers

Floating-point

Other predefined types

A unicode string with no special upper bound.

Page 31 of 65

The C# Station Tutorial


http://www.csharp-station.com/Tutorial/CSharp/SmartConsoleSetup.aspx

Introduction:
Welcome to the C# Station Tutorial This is a set of lessons suited for beginning to intermediate
programmers or anyone who would like to gain familiarity with the C# programming language. These
lessons will help you get a quick head-start with C# programming.
To get started, you will need a compiler and an editor. There are several options for obtaining a
compiler to write C# programs. A free option is to download the .NET Frameworks SDK and use
Notepad. Of course there are many editor and IDE options available, so see the Tools section to select
the option that's right for you. Most of the examples in these tutorials run as console programs.
Microsoft Visual Studio is also available in multiple versions as well as a free download for Visual Studio
Express.
This tutorial is a work in progress. It's quality is a product of volunteer reviews and valuable feedback
received from many readers. Please visit periodically for the latest updates and new lessons.
Once you've completed this tutorial, you may be interested in additional resources to continue learning
C#. There are also additional Articleson this site.
I hope you enjoy the tutorial, and best of luck!
Joe
Follow Joe Mayo on Twitter.

References:
C# Language Reference and Specifications
Standard ECMA-334 C# Language Specification

Lessons:
Lesson 01: Getting Started
Lesson 02: Expressions, Types, and Variables
Lesson 03: Control Statements - Selection
Lesson 04: Control Statements - Loops
Lesson 05: Methods
Lesson 06: Namespaces
Lesson 07: Introduction to Classes
Lesson 08: Class Inheritance

Page 32 of 65
Lesson 09: Polymorphism
Lesson 10: Properties
Lesson 11: Indexers
Lesson 12: Structs
Lesson 13: Interfaces
Lesson 14: Introduction to Delegates and Events
Lesson 15: Introduction to Exception Handling
Lesson 16: Using Attributes
Lesson 17: Enums
Lesson 18: Overloading Operators
Lesson 19: Encapsulation
Lesson 20: Introduction to Generic Collections
Lesson 21: Anonymous Methods
Lesson 22: Topics on C# Type
Lesson 23: Working with Nullable Types

Page 33 of 65

The C# Station Tutorial


http://www.csharp-station.com/Tutorial/CSharp/Lesson02
Lesson 2: Operators, Types, and Variables
This lesson introduces C# operators, types, and variables. Its goal is to meet the following objectives:

Understand what a variable is.

Familiarization with C# built-in types.

Get an introduction to C# operators.

Learn how to use Arrays.

Variables and Types


"Variables" are simply storage locations for data. You can place data into them and retrieve their
contents as part of a C# expression. The interpretation of the data in a variable is controlled through
"Types".
C# is a "Strongly Typed" language. Thus all operations on variables are performed with consideration of
what the variable's "Type" is. There are rules that define what operations are legal in order to maintain
the integrity of the data you put in a variable.
The C# simple types consist of the Boolean type and three numeric types - Integrals, Floating Point,
Decimal, and String. The term "Integrals", which is defined in the C# Programming Language
Specification, refers to the classification of types that include sbyte, byte, short, ushort, int, uint, long,
ulong, and char. More details are available in the Integral Types section later in this lesson. The term
"Floating Point" refers to the float and double types, which are discussed, along with the decimal type,
in more detail in the Floating Point and Decimal Types section later in this lesson. The string type
represents a string of characters and is discussed in The String Type section, later in this lesson. The
next section introduces the boolean type.

The Boolean Type


Boolean types are declared using the keyword, bool. They have two values: true or false. In other
languages, such as C and C++, boolean conditions can be satisfied where 0 means false and anything
else means true. However, in C# the only values that satisfy a boolean condition is true and false,
which are official keywords. Listing 2-1 shows one of many ways that boolean types can be used in a
program.

Listing 2-1. Displaying Boolean Values: Boolean.cs


using System;
class Booleans
{
public static void Main()
{
bool content = true;
bool noContent = false;
Console.WriteLine("It is {0} that C# Station provides C# programming language
content.", content);

Page 34 of 65
Console.WriteLine("The statement above is not {0}.", noContent);
}
}
In Listing 2-1, the boolean values are written to the console as a part of a sentence. The only legal
values for the bool type are either true orfalse, as shown by the assignment
of true to content and false to noContent. When run, this program produces the following output:

It is True that C# Station provides C# programming language content.


The statement above is not False.

Integral Types
In C#, an integral is a category of types. For anyone confused because the word Integral sounds like a
mathematical term, from the perspective of C# programming, these are actually defined as Integral
types in the C# programming language specification. They are whole numbers, either signed or
unsigned, and the char type. The char type is a Unicode character, as defined by the Unicode Standard.
For more information, visit The Unicode Home Page. table 2-1 shows the integral types, their size, and
range.

Table 2-1. The Size and Range of C# Integral Types


Type

Size (in bits)

Range

sbyte

-128 to 127

byte

0 to 255

short

16

-32768 to 32767

ushort

16

0 to 65535

int

32

-2147483648 to 2147483647

uint

32

0 to 4294967295

long

64

-9223372036854775808 to 9223372036854775807

ulong

64

0 to 18446744073709551615

char

16

0 to 65535

Integral types are well suited for those operations involving whole number calculations. The char type is
the exception, representing a single Unicode character. As you can see from the table above, you have
a wide range of options to choose from, depending on your requirements.

Floating Point and Decimal Types


A C# floating point type is either a float or double. They are used any time you need to represent a real
number, as defined by IEEE 754. For more information on IEEE 754, visit the IEEE Web Site. Decimal
types should be used when representing financial or money values. table 2-2 shows the floating point
and decimal types, their size, precision, and range.

Page 35 of 65
Table 2-2. The Floating Point and Decimal Types with Size, precision, and Range
Type

Size (in bits)

precision

Range

float

32

7 digits

double

64

15-16 digits

decimal

128

28-29 decimal places

1.5 x 10-45 to 3.4 x 1038


5.0 x 10-324 to 1.7 x 10308
1.0 x 10-28 to 7.9 x 1028

Floating point types are used when you need to perform operations requiring fractional representations.
However, for financial calculations, the decimal type is the best choice because you can avoid rounding
errors.

The string Type


A string is a sequence of text characters. You typically create a string with a string literal, enclosed in
quotes: "This is an example of a string." You've seen strings being used in Lesson 1, where we used
the Console.WriteLine method to send output to the console.
Some characters aren't printable, but you still need to use them in strings. Therefore, C# has a special
syntax where characters can be escaped to represent non-printable characters. For example, it is
common to use newlines in text, which is represented by the '\n' char. The backslash, '\', represents the
escape. When preceded by the escape character, the 'n' is no longer interpreted as an alphabetical
character, but now represents a newline.
You may be now wondering how you could represent a backslash character in your code. We have to
escape that too by typing two backslashes, as in '\\'. table 2-3 shows a list of common escape
sequences.

Table 2-3. C# Character Escape Sequences


Escape Sequence

Meaning

\'

Single Quote

\"

Double Quote

\\

Backslash

\0

Null, not the same as the C# null value

\a

Bell

\b

Backspace

\f

form Feed

\n

Newline

\r

Carriage Return

\t

Horizontal Tab

\v

Vertical Tab

Another useful feature of C# strings is the verbatim literal, which is a string with a @ symbol prefix, as
in @"Some string". Verbatim literals make escape sequences translate as normal characters to enhance
readability. To appreciate the value of verbatim literals, consider a path statement such
as "c:\\topdir\\subdir\\subdir\\myapp.exe". As you can see, the backslashes are escaped, causing the

Page 36 of 65
string to be less readable. You can improve the string with a verbatim literal, like
this: @"c:\topdir\subdir\subdir\myapp.exe".
That is fine, but now you have the problem where quoting text is not as easy. In that case, you would
specify double double quotes. For example, the string "copy \"c:\\source file name with spaces.txt\"
c:\\newfilename.txt" would be written as the verbatim literal @"copy ""c:\source file name with
spaces.txt"" c:\newfilename.txt".

C# Operators
Results are computed by building expressions. These expressions are built by combining variables and
operators together into statements. The following table describes the allowable operators, their
precedence, and associativity.

Table 2-4. Operators with their precedence and Associativity


Category (by
precedence)

Operator(s)

Associativity

Primary

x.y f(x) a[x] x++ x-- new typeof default checked


unchecked delegate

left

Unary

+ - ! ~ ++x --x (T)x

right

Multiplicative

* / %

left

Additive

+ -

left

Shift

<< >>

left

Relational

< > <= >= is as

left

Equality

== !=

right

Logical AND

&

left

Logical XOR

left

Logical OR

left

Conditional AND

&&

left

Conditional OR

||

left

Null Coalescing

??

left

Ternary

?:

right

Assignment

= *= /= %= += -= <<= >>= &= ^= |= =>

right

Left associativity means that operations are evaluated from left to right. Right associativity mean all
operations occur from right to left, such as assignment operators where everything to the right is
evaluated before the result is placed into the variable on the left.

Page 37 of 65
Most operators are either unary or binary. Unary operators form expressions on a single variable, but
binary operators form expressions with two variables. Listing 2-2 demonstrates how unary operators
are used.

Listing 2-2. Unary Operators: Unary.cs


using System;
class Unary
{
public static void Main()
{
int unary = 0;
int preIncrement;
int preDecrement;
int postIncrement;
int postDecrement;
int positive;
int negative;
sbyte bitNot;
bool logNot;
preIncrement = ++unary;
Console.WriteLine("pre-Increment: {0}", preIncrement);
preDecrement = --unary;
Console.WriteLine("pre-Decrement: {0}", preDecrement);
postDecrement = unary--;
Console.WriteLine("Post-Decrement: {0}", postDecrement);
postIncrement = unary++;
Console.WriteLine("Post-Increment: {0}", postIncrement);
Console.WriteLine("Final Value of Unary: {0}", unary);
positive = -postIncrement;
Console.WriteLine("Positive: {0}", positive);
negative = +postIncrement;
Console.WriteLine("Negative: {0}", negative);
bitNot = 0;
bitNot = (sbyte)(~bitNot);
Console.WriteLine("Bitwise Not: {0}", bitNot);
logNot = false;
logNot = !logNot;
Console.WriteLine("Logical Not: {0}", logNot);
}
}
When evaluating expressions, post-increment (x++) and post-decrement (x--) operators return their
current value and then apply the operators. However, when using pre-increment (++x) and predecrement (--x) operators, the operator is applied to the variable prior to returning the final value.

Page 38 of 65
In Listing 2-2, the unary variable is initialized to zero. When the pre-increment (++x) operator is
used, unary is incremented to 1 and the value 1 is assigned to the preIncrement variable. The predecrement (--x) operator
turns unary back
to
a
0
and
then
assigns
the
value
to
thepreDecrement variable.
When the post-decrement (x--) operator is used, the value of unary, 0, is placed into
the postDecrement variable and then unary is decremented to -1. Next the post-increment (x+
+) operator moves the current value of unary, -1, to the postIncrement variable and then
increments unary to 0.
The variable bitNot is initialized to 0 and the bitwise not (~) operator is applied. The bitwise
not (~) operator flips the bits in the variable. In this case, the binary representation of 0, "00000000",
was transformed into -1, "11111111".
While the (~) operator works by flipping bits, the logical negation operator (!) is a logical operator that
works on bool values, changing true tofalse or false to true. In the case of the logNot variable in Listing
2-2, the value is initialized to false, and the next line applies the logical negation operator, (!), which
returns true and reassigns the new value, true, to logNot. Essentially, it is toggling the value of
the bool variable,logNot.
The setting of positive is a little tricky. At the time that it is set, the postIncrement variable is equal to
-1. Applying the minus (-) operator to a negative number results in a positive number, meaning
that positive will equal 1, instead of -1. The minus operator (-), which is not the same as the predecrement operator (--), doesn't change the value of postInc - it just applies a sign negation. The plus
operator (+) doesn't affect the value of a number, assigning negative with the same value
as postIncrement, -1.
Notice the expression (sbyte)(~bitNot). Any operation performed on types sbyte, byte, short,
or ushort return int values. To assign the result into the bitNot variable we had to use a cast, (Type),
operator, where Type is the type you wish to convert to (in this case - sbyte). The cast operator is
shown as the Unary operator, (T)x, in table 2-4. Cast operators must be performed explicity when you
go from a larger type to a smaller type because of the potential for lost data. Generally speaking,
assigning a smaller type to a larger type is no problem, since the larger type has room to hold the
entire value. Also be aware of the dangers of casting between signed and unsigned types. You want to
be sure to preserve the integrity of your data. Many basic programming texts contain good descriptions
of bit representations of variables and the dangers of explicit casting.
Here's the output from the Listing 2-2:

pre-Increment: 1
pre-Decrement 0
Post-Decrement: 0
Post-Increment: -1
Final Value of Unary: 0
Positive: 1
Negative: -1
Bitwise Not: -1
Logical Not: true

In addition to unary operators, C# has binary operators that form expressions of two variables. Listing
2-3 shows how to use the binary operators.

Page 39 of 65

Listing 2-3. Binary Operators: Binary.cs


using System;
class Binary
{
public static void Main()
{
int x, y, result;
float floatresult;
x = 7;
y = 5;
result = x+y;
Console.WriteLine("x+y: {0}", result);
result = x-y;
Console.WriteLine("x-y: {0}", result);
result = x*y;
Console.WriteLine("x*y: {0}", result);
result = x/y;
Console.WriteLine("x/y: {0}", result);
floatresult = (float)x/(float)y;
Console.WriteLine("x/y: {0}", floatresult);
result = x%y;
Console.WriteLine("x%y: {0}", result);
result += x;
Console.WriteLine("result+=x: {0}", result);
}
}
And here's the output:

x+y: 12
x-y: 2
x*y: 35
x/y: 1
x/y: 1.4
x%y: 2
result+=x: 9
Listing 2-3 shows several examples of binary operators. As you might expect, the results of addition
(+), subtraction (-), multiplication (*), and division (/) produce the expected mathematical results.
The floatresult variable is a floating point type. We explicitly cast the integer variables x and y to
calculate a floating point value.
There is also an example of the remainder(%) operator. It performs a division operation on two values
and returns the remainder.
The last statement shows another form of the assignment with operation (+=) operator. Any time you
use the assignment with operation operator, it is the same as applying the binary operator to both the

Page 40 of 65
left hand and right hand sides of the operator and putting the results into the left hand side. The
example could have been written as result = result + x; and returned the same value.

The Array Type


Another data type is the Array, which can be thought of as a container that has a list of storage
locations for a specified type. When declaring an Array, specify the type, name, dimensions, and size.

Listing 2-4. Array Operations: Array.cs


using System;
class Array
{
public static void Main()
{
int[] myInts = { 5, 10, 15 };
bool[][] myBools = new bool[2][];
myBools[0] = new bool[2];
myBools[1] = new bool[1];
double[,] myDoubles = new double[2, 2];
string[] myStrings = new string[3];
Console.WriteLine("myInts[0]: {0}, myInts[1]: {1}, myInts[2]: {2}",
myInts[0], myInts[1], myInts[2]);
myBools[0][0] = true;
myBools[0][1] = false;
myBools[1][0] = true;
Console.WriteLine("myBools[0][0]: {0}, myBools[1][0]: {1}", myBools[0][0],
myBools[1][0]);
myDoubles[0, 0] = 3.147;
myDoubles[0, 1] = 7.157;
myDoubles[1, 1] = 2.117;
myDoubles[1, 0] = 56.00138917;
Console.WriteLine("myDoubles[0, 0]: {0}, myDoubles[1, 0]: {1}",
myDoubles[0, 0], myDoubles[1, 0]);
myStrings[0] = "Joe";
myStrings[1] = "Matt";
myStrings[2] = "Robert";
Console.WriteLine("myStrings[0]: {0}, myStrings[1]: {1}, myStrings[2]: {2}",
myStrings[0], myStrings[1], myStrings[2]);
}
}
And here's the output:

myInts[0]: 5, myInts[1]: 10, myInts[2]: 15


myBools[0][0]: true, myBools[1][0]: true
myDoubles[0, 0]: 3.147, myDoubles[1, 0]: 56.00138917
myStrings[0]: Joe, myStrings[1]: Matt, myStrings[2]: Robert
Listing 2-4 shows different implementations of Arrays. The first example is the myInts Array, which is a
single-dimension array. It is initialized at declaration time with explicit values.

Page 41 of 65
Next is a jagged array, myBools. It is essentially an array of arrays. We needed to use the new operator
to instantiate the size of the primary array and then use the new operator again for each sub-array.
The third example is a two dimensional array, myDoubles. Arrays can be multi-dimensional, with each
dimension separated by a comma. It must also be instantiated with the new operator.
One of the differences between jagged arrays, myBools[][], and multi-dimension arrays, myDoubles[,],
is that a multi-dimension array will allocate memory for every element of each dimension, whereas a
jagged array will only allocate memory for the size of each array in each dimension that you define.
Most of the time, you'll be using multi-dimension arrays, if you need multiple dimensions, and will only
use jagged arrays in very special circumstances when you are able to save significant memory by
explicitly specifying the sizes of the arrays in each dimension.
Finally, we have the single-dimensional array of string types, myStrings.
In each case, you can see that array elements are accessed by identifying the integer index for the item
you wish to refer to. Arrays sizes can be any int type value. Their indexes begin at 0.

Summary
A variable is an identifier with a type that holds a value of that type. Simple types include the integrals,
floating points, decimal, and bool. C# has several mathematical and logical operators that participate in
forming expressions. C# also offers the single dimension, multi-dimension and jagged array types.
In this lesson you learned how to write simple statements and code a program that works linearly from
start to finish. However, this is not as useful as it can be because you need to be able to make decisions
and execute different blocks of code depending on different conditions. I invite you to return for Lesson
3: Control Statements - Selection, where you can learn how to branch your logic for more powerful
decision making.

Page 42 of 65

06. Looping Arrays and Lists

The C# Station Tutorial


http://www.csharp-station.com/Tutorial/CSharp/Lesson04
Lesson 4: Control Statements - Loops
In the last lesson, you learned how to create a simple loop by using the goto statement. I advised you
that this is not the best way to perform loops in C#. The information in this lesson will teach you the
proper way to execute iterative logic with the various C# looping statements. Its goal is to meet the
following objectives:

Learn the while loop.

Learn the do loop.

Learn the for loop.

Learn the foreach loop.

Complete your knowledge of the break statement.

Teach you how to use the continue statement.

The while Loop


A while loop will check a condition and then continues to execute a block of code as long as the
condition evaluates to a boolean value of true. Its syntax is as follows: while (<boolean expression>)
{ <statements> }. The statements can be any valid C# statements. The boolean expression is
evaluated before any code in the following block has executed. When the boolean expression evaluates
to true, the statements will execute. Once the statements have executed, control returns to the
beginning of the while loop to check the boolean expression again.
When the boolean expression evaluates to false, the while loop statements are skipped and execution
begins after the closing brace of that block of code. Before entering the loop, ensure that variables
evaluated in the loop condition are set to an initial state. During execution, make sure you update
variables associated with the boolean expression so that the loop will end when you want it to. Listing
4-1 shows how to implement a while loop.

Listing 4-1. The While Loop: WhileLoop.cs


using System;
class WhileLoop
{
public static void Main()
{
int myInt = 0;
while (myInt < 10)
{
Console.Write("{0} ", myInt);
myInt++;

Page 43 of 65
}
Console.WriteLine();
}
}
Listing 4-1 shows a simple while loop. It begins with the keyword while, followed by a boolean
expression. All control statements use boolean expressions as their condition for entering/continuing
the loop. This means that the expression must evaluate to either a true or false value. In this case we
are checking the myInt variable to see if it is less than (<) 10. Since myInt was initialized to 0, the
boolean expression will return true the first time it is evaluated. When the boolean expression evaluates
to true, the block immediately following the boolean expression will be executed.
Within the while block we print the number and a space to the console. Then we increment (+
+) myInt to the next integer. Once the statements in the while block have executed, the boolean
expression is evaluated again. This sequence will continue until the boolean expression evaluates
to false. Once the boolean expression is evaluated as false, program control will jump to the first
statement following thewhile block. In this case, we will write the numbers 0 through 9 to the console,
exit the while block, and print a new line to the console.

The do Loop
A do loop is similar to the while loop, except that it checks its condition at the end of the loop. This
means that the do loop is guaranteed to execute at least one time. On the other hand, a while loop
evaluates its boolean expression at the beginning and there is generally no guarantee that the
statements inside the loop will be executed, unless you program the code to explicitly do so. One
reason you may want to use a do loop instead of a while loop is to present a message or menu such as
the one in Listing 4-2 and then retrieve input from a user.

Listing 4-2. The Do Loop: DoLoop.cs


using System;
class DoLoop
{
public static void Main()
{
string myChoice;
do
{
// Print A Menu
Console.WriteLine("My Address Book\n");
Console.WriteLine("A - Add New Address");
Console.WriteLine("D - Delete Address");
Console.WriteLine("M - Modify Address");
Console.WriteLine("V - View Addresses");
Console.WriteLine("Q - Quit\n");
Console.WriteLine("Choice (A,D,M,V,or Q): ");
// Retrieve the user's choice
myChoice = Console.ReadLine();
// Make a decision based on the user's choice
switch(myChoice)
{

Page 44 of 65
case "A":
case "a":
Console.WriteLine("You wish to add an address.");
break;
case "D":
case "d":
Console.WriteLine("You wish to delete an address.");
break;
case "M":
case "m":
Console.WriteLine("You wish to modify an address.");
break;
case "V":
case "v":
Console.WriteLine("You wish to view the address list.");
break;
case "Q":
case "q":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("{0} is not a valid choice", myChoice);
break;
}
// Pause to allow the user to see the results
Console.Write("press Enter key to continue...");
Console.ReadLine();
Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q"); // Keep going until the user
wants to quit
}
}
Listing 4-2 shows a do loop in action. The syntax of the do loop is do { <statements> } while
(<boolean expression>);. The statements can be any valid C# programming statements you like. The
boolean expression is the same as all others we've encountered so far. It returns either true or false.
In the Main method, we declare the variable myChoice of type string. Then we print a series of
statements to the console. This is a menu of choices for the user. We must get input from the user,
which is in the form of a Console.ReadLine method which returns the user's value into
the myChoice variable. We must take the user's input and process it. A very efficient way to do this is
with a switch statement. Notice that we've placed matching upper and lower case letters together to
obtain the same functionality. This is the only legal way to have automatic fall through between cases.
If you were to place any statements between two cases, you would not be able to fall through. Another
point is that we used the default: case, which is a very good habit for the reasons stated in Lesson 3:
Control Statements - Selection.

The for Loop


A for loop works like a while loop, except that the syntax of the for loop includes initialization and
condition modification. for loops are appropriate when you know exactly how many times you want to
perform the statements within the loop. The contents within the for loop parentheses hold three
sections separated by semicolons (<initializer list>; <boolean expression>; <iterator list>)
{ <statements> }.

Page 45 of 65
The initializer list is a comma separated list of expressions. These expressions are evaluated only once
during the lifetime of the for loop. This is a one-time operation, before loop execution. This section is
commonly used to initialize an integer to be used as a counter.
Once the initializer list has been evaluated, the for loop gives control to its second section, the boolean
expression. There is only one boolean expression, but it can be as complicated as you like as long as
the result evaluates to true or false. The boolean expression is commonly used to verify the status of a
counter variable.
When the boolean expression evaluates to true, the statements within the curly braces of the for loop
are executed. After executing for loop statements, control moves to the top of loop and executes the
iterator list, which is normally used to increment or decrement a counter. The iterator list can contain a
comma separated list of statements, but is generally only one statement. Listing 4-3 shows how to
implement a forloop. The purpose of the program is to print only odd numbers less than 10.

Listing 4-3. The For Loop: ForLoop.cs


using System;
class ForLoop
{
public static void Main()
{
for (int i=0; i < 20; i++)
{
if (i == 10)
break;
if (i % 2 == 0)
continue;
Console.Write("{0} ", i);
}
Console.WriteLine();
}
}
Normally, for loop statements execute from the opening curly brace to the closing curly brace without
interruption. However, in Listing 4-3, we've made a couple exceptions. There are a couple if statements
disrupting the flow of control within the for block.
The first if statement checks to see if i is equal to 10. Now you see another use of the break statement.
Its behavior is similar to the selection statements, as discussed in Lesson 3: Control Statements Selection. It simply breaks out of the loop at that point and transfers control to the first statement
following the end of the for block.
The second if statement uses the remainder operator to see if i is a multiple of 2. This will evaluate
to true when i is divided by 2 with a remainder equal to zero, (0). When true, the continue statement is
executed, causing control to skip over the remaining statements in the loop and transfer back to the
iterator list. By arranging the statements within a block properly, you can conditionally execute them
based upon whatever condition you need.
When program control reaches either a continue statement or end of block, it transfers to the third
section within the for loop parentheses, the iterator list. This is a comma separated list of actions that
are executed after the statements in the for block have been executed. Listing 4-3 is a typical action,
incrementing the counter. Once this is complete, control transfers to the boolean expression for
evaluation.

Page 46 of 65
Similar to the while loop, a for loop will continue as long as the boolean expression is true. When the
boolean expression becomes false, control is transferred to the first statement following the for block.
For this tutorial, I chose to implement break and continue statements in Listing 4-3 only. However, they
may be used in any of the loop statements.

The foreach Loop


A foreach loop is used to iterate through the items in a list. It operates on arrays or collections such as
ArrayList, which can be found in the System.Collections namespace. The syntax of a foreach loop
is foreach (<type> <iteration variable> in <list>) { <statements> }. The type is the type of item
contained in the list. For example, if the type of the list was int[] then the type would be int.
The iteration variable is an identifier that you choose, which could be anything but should be
meaningful. For example, if the list contained an array of people's ages, then a meaningful name for
item name would be age.
The in keyword is required.
As mentioned earlier, the list could be either an array or a collection. You learned about arrays in Lesson
02: Operators, Types, and Variables. You can also iterate over C# generic collections also, described
in Lesson 20: Introduction to Generic Collections.
While iterating through the items of a list with a foreach loop, the list is read-only. This means that you
can't modify the iteration variable within a foreach loop. There is a subtlety here; Later, you'll learn how
to create custom types, called class and struct, that can contain multiple fields. You can change the
fields of the class or struct, but not the iteration variable for the class or struct itself in a foreach loop.
On each iteration through a foreach loop the list is queried for a new value. As long as the list can
return a value, this value will be put into the read-only iteration variable, causing the statements in
the foreach block to be executed. When the collection has been fully traversed, control will transfer to
the first executable statement following the end of the foreach block. Listing 4-4 demonstrates how to
use a foreachloop.

Listing 4-4. The ForEach Loop: ForEachLoop.cs


using System;
class ForEachLoop
{
public static void Main()
{
string[] names = {"Cheryl", "Joe", "Matt", "Robert"};
foreach (string person in names)
{
Console.WriteLine("{0} ", person);
}
}
}
In Listing 4-4, the first thing we've done inside the Main method is
the names array with 4 strings. This is the list used in the foreach loop.

declare

and initialize

Page 47 of 65
In the foreach loop, we've used a string variable, person, as the item name, to hold each element of
the names array. As long as there are names in the array that have not been returned,
the Console.WriteLine method will print each value of the person variable to the screen.

Summary
Loops allow you to execute a block of statements repeatedly. C# offers several statements to construct
loops with, including the while, do, for, and foreach loops. while loops execute a block of statements as
long as an expression is true, do loops execute a block of statements at least once and then keep going
as long as a condition is true, for loops execute a block of statements a specified amount of times,
and foreach loops execute a block of statements for each item in a collection. Normally a block of
statements will execute from beginning to end. However, the normal flow of a loop can be changed with
the break and continue statements.
So far, the only method you've seen in this tutorial is the Main method, which is the entry point of a C#
application. However, you are probably wanting to write larger programs to test your new knowledge.
This requires breaking up the code into methods to keep it organized and logical. For this, I invite you
to return for Lesson 5: Introduction to Methods, where you can learn new techniques of organizing your
code.

Page 48 of 65

Arrays Tutorial
This tutorial describes arrays and shows how they work in C#.

Further Reading

Arrays

12. Arrays

foreach, in

Collection Classes Tutorial

Tutorial
This tutorial is divided into the following sections:

Arrays in General

Declaring Arrays

Initializing Arrays

Accessing Array Members

Arrays are Objects

Using foreach with Arrays

Arrays in General
C# arrays are zero indexed; that is, the array indexes start at zero. Arrays in C# work similarly to how
arrays work in most other popular languages There are, however, a few differences that you should be
aware of.
When declaring an array, the square brackets ([]) must come after the type, not the identifier. Placing
the brackets after the identifier is not legal syntax in C#.

int[] table; // not int table[];

Page 49 of 65
Another detail is that the size of the array is not part of its type as it is in the C language. This allows
you to declare an array and assign any array of int objects to it, regardless of the array's length.
int[] numbers; // declare numbers as an int array of any size
numbers = new int[10]; // numbers is a 10-element array
numbers = new int[20]; // now it's a 20-element array

Declaring Arrays
C# supports single-dimensional arrays, multidimensional arrays (rectangular arrays), and array-ofarrays (jagged arrays). The following examples show how to declare different kinds of arrays:
Single-dimensional arrays:
int[] numbers;
Multidimensional arrays:
string[,] names;
Array-of-arrays (jagged):
byte[][] scores;
Declaring them (as shown above) does not actually create the arrays. In C#, arrays are objects
(discussed later in this tutorial) and must be instantiated. The following examples show how to create
arrays:
Single-dimensional arrays:
int[] numbers = new int[5];
Multidimensional arrays:
string[,] names = new string[5,4];
Array-of-arrays (jagged):
byte[][] scores = new byte[5][];
for (int x = 0; x < scores.Length; x++)
{
scores[x] = new byte[4];
}
You can also have larger arrays. For example, you can have a three-dimensional rectangular array:
int[,,] buttons = new int[4,5,3];
You can even mix rectangular and jagged arrays. For example, the following code declares a singledimensional array of three-dimensional arrays of two-dimensional arrays of type int:
int[][,,][,] numbers;

Page 50 of 65

Example
The following is a complete C# program that declares and instantiates arrays as discussed above.
// arrays.cs
using System;
class DeclareArraysSample
{
public static void Main()
{
// Single-dimensional array
int[] numbers = new int[5];
// Multidimensional array
string[,] names = new string[5,4];
// Array-of-arrays (jagged array)
byte[][] scores = new byte[5][];
// Create the jagged array
for (int i = 0; i < scores.Length; i++)
{
scores[i] = new byte[i+3];
}
// Print length of each row
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine("Length of row {0} is {1}", i, scores[i].Length);
}
}
}

Output
Length
Length
Length
Length
Length

of
of
of
of
of

row
row
row
row
row

0
1
2
3
4

is
is
is
is
is

3
4
5
6
7

Initializing Arrays
C# provides simple and straightforward ways to initialize arrays at declaration time by enclosing the
initial values in curly braces ({}). The following examples show different ways to initialize different kinds
of arrays.

Page 51 of 65
Note If you do not initialize an array at the time of declaration, the array members are automatically
initialized to the default initial value for the array type. Also, if you declare the array as a field of a type,
it will be set to the default value null when you instantiate the type.

Single-Dimensional Array
int[] numbers = new int[5] {1, 2, 3, 4, 5};
string[] names = new string[3] {"Matt", "Joanne", "Robert"};
You can omit the size of the array, like this:
int[] numbers = new int[] {1, 2, 3, 4, 5};
string[] names = new string[] {"Matt", "Joanne", "Robert"};
You can also omit the new operator if an initializer is provided, like this:
int[] numbers = {1, 2, 3, 4, 5};
string[] names = {"Matt", "Joanne", "Robert"};

Multidimensional Array
int[,] numbers = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = new string[2, 2] { {"Mike","Amy"}, {"Mary","Albert"} };
You can omit the size of the array, like this:
int[,] numbers = new int[,] { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = new string[,] { {"Mike","Amy"}, {"Mary","Albert"} };
You can also omit the new operator if an initializer is provided, like this:
int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = { {"Mike", "Amy"}, {"Mary", "Albert"} };

Jagged Array (Array-of-Arrays)


You can initialize jagged arrays like this example:
int[][] numbers = new int[2][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} };
You can also omit the size of the first array, like this:
int[][] numbers = new int[][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} };
-orint[][] numbers = { new int[] {2,3,4}, new int[] {5,6,7,8,9} };
Notice that there is no initialization syntax for the elements of a jagged array.

Accessing Array Members

Page 52 of 65
Accessing array members is straightforward and similar to how you access array members in C/C++.
For example, the following code creates an array called numbers and then assigns a 5 to the fifth
element of the array:
int[] numbers = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
numbers[4] = 5;
The following code declares a multidimensional array and assigns 5 to the member located at [1, 1]:
int[,] numbers = { {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10} };
numbers[1, 1] = 5;
The following is a declaration of a single-dimension jagged array that contains two elements. The first
element is an array of two integers, and the second is an array of three integers:
int[][] numbers = new int[][] { new int[] {1, 2}, new int[] {3, 4, 5}
};
The following statements assign 58 to the first element of the first array and 667 to the second element
of the second array:
numbers[0][0] = 58;
numbers[1][1] = 667;

Arrays are Objects


In C#, arrays are actually objects. System.Array is the abstract base type of all array types. You can
use the properties, and other class members, that System.Array has. An example of this would be
using the Length property to get the length of an array. The following code assigns the length of
the numbers array, which is 5, to a variable calledLengthOfNumbers:
int[] numbers = {1, 2, 3, 4, 5};
int LengthOfNumbers = numbers.Length;
The System.Array class provides many other useful methods/properties, such as methods for sorting,
searching, and copying arrays.

Using foreach on Arrays


C# also provides the foreach statement. This statement provides a simple, clean way to iterate through
the elements of an array. For example, the following code creates an array called numbers and iterates
through it with the foreachstatement:
int[] numbers = {4, 5, 6, 1, 2, 3, -2, -1, 0};
foreach (int i in numbers)
{
System.Console.WriteLine(i);
}

Page 53 of 65
With multidimensional arrays, you can use the same method to iterate through the elements, for
example:
int[,] numbers = new int[3, 2] {{9, 99}, {3, 33}, {5, 55}};
foreach(int i in numbers)
{
Console.Write("{0} ", i);
}
The output of this example is:
9 99 3 33 5 55
However, with multidimensional arrays, using a nested for loop gives you more control over the array
elements.

Page 54 of 65

The C# Station Tutorial


http://www.csharp-station.com/Tutorial/CSharp/Lesson20

Lesson 20: Introduction to Generic Collections


All the way back in Lesson 02, you learned about arrays and how they allow you to add and retrieve a
collection of objects. Arrays are good for many tasks, but C# v2.0 introduced a new feature called
generics. Among many benefits, one huge benefit is that generics allow us to create collections that
allow us to do more than allowed by an array. This lesson will introduce you to generic collections and
how they can be used. Here are the objectives for this lesson:

Understand how generic collections can benefit you

Learn how to create and use a generic List

Write code that implements a generic Dictionary

What Can Generics Do For Me?


Throughout this tutorial, you've learned about types, whether built-in (int, float, char) or custom
(Shape, Customer, Account). In .NET v1.0 there were collections, such as the ArrayList for working with
groups of objects. An ArrayList is much like an array, except it could automatically grow and offered
many convenience methods that arrays don't have. The problem with ArrayList and all the other .NET
v1.0 collections is that they operate on type object. Since all objects derive from the object type, you
can assign anything to an ArrayList. The problem with this is that you incur performance overhead
converting value type objects to and from the object type and a single ArrayListcould accidentally hold
different types, which would cause hard to find errors at runtime because you wrote code to work with
one type. Generic collections fix these problems.
A generic collection is strongly typed (type safe), meaning that you can only put one type of object into
it. This eliminates type mismatches at runtime. Another benefit of type safety is that performance is
better with value type objects because they don't incur overhead of being converted to and from
type object. With generic collections, you have the best of all worlds because they are strongly typed,
like arrays, and you have the additional functionality, like ArrayList and other non-generic collections,
without the problems.
The next section will show you how to use a generic List collection.

Creating Generic List<T> Collections


The pattern for using a generic List collection is similar to arrays. You declare the List, populate its
members, then access the members. Here's a code example of how to use a List:

List<int> myInts = new List<int>();


myInts.Add(1);
myInts.Add(2);
myInts.Add(3);
for (int i = 0; i < myInts.Count; i++)
{
Console.WriteLine("MyInts: {0}", myInts[i]);
}
The first thing you should notice is the generic collection List<int>, which is referred to as List of int. If
you looked in the documentation for this class, you would find that it is defined as List<T>,
where T could be any type. For example, if you wanted the list to work on string orCustomer objects,

Page 55 of 65
you
could
define
them
as List<string> or List<Customer> and
they
only string or Customer objects. In the example above, myInts holds only type int.

would

hold

Using the Add method, you can add as many int objects to the collection as you want. This is different
from arrays, which have a fixed size. The List<T> class has many more methods you can use, such
as Contains, Remove, and more.
There are two parts of the for loop that you need to know about. First, the condition uses
the Count property of myInts. This is another difference between collections and arrays in that an array
uses a Length property for the same thing. Next, the way to read from a specific position in
the List<T> collection, myInts[i], is the exact same syntax you use with arrays.
The next time you start to use a single-dimension array, consider using a List<T> instead. That said, be
sure to let your solution fit the problem and use the best tool for the job. i.e. it's common to work
with byte[] in many places in the .NET Framework.

Working with Dictionary<TKey, TValue> Collections


Another very useful generic collection is the Dictionary, which works with key/value pairs. There is a
non-generic collection, called a Hashtablethat does the same thing, except that it operates on
type object. However, as explained earlier in this lesson, you want to avoid the non-generic collections
and use thier generic counterparts instead. The scenario I'll use for this example is that you have a list
of Customers that you need to work with. It would be natural to keep track of these Customers via
their CustomerID. The Dictionary example will work with instances of the following Customer class:
public class Customer
{
public Customer(int id, string name)
{
ID = id;
Name = name;
}
private int m_id;
public int ID
{
get { return m_id; }
set { m_id = value; }
}
private string m_name;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
}
The Customer class above has a constructor to make it easier to initialize. It also exposes its state via
public properties. It isn't very sophisticated at this point, but that's okay because its only purpose is to
help you learn how to use a Dictionary collection. The following example populates
a Dictionary collection with Customer objects and then shows you how to extract entries from
the Dictionary:

Dictionary<int, Customer> customers = new Dictionary<int, Customer>();


Customer cust1 = new Customer(1, "Cust 1");
Customer cust2 = new Customer(2, "Cust 2");
Customer cust3 = new Customer(3, "Cust 3");
customers.Add(cust1.ID, cust1);

Page 56 of 65
customers.Add(cust2.ID, cust2);
customers.Add(cust3.ID, cust3);
foreach (KeyValuePair<int, Customer> custKeyVal in customers)
{
Console.WriteLine(
"Customer ID: {0}, Name: {1}",
custKeyVal.Key,
custKeyVal.Value.Name);
}
The customers variable is declared as a Dictionary<int, Customer>. Considering that the formal
declaration of Dictionary is Dictionary<TKey, TValue>, the meaning of customers is that it is
a Dictionary where the key is type int and the value is type Customer. Therefore, any time you add an
entry to the Dictionary, you must provide the key because it is also the key that you will use to extract
a specified Customer from the Dictionary.
I created three Customer objects, giving each an ID and a Name. I'll use the ID as the key and the
entire Customer object as the value. You can see this in the calls to Add, where custX.ID is added as
the key (first parameter) and the custX instance is added as the value (second parameter).
Extracting information from a Dictionary is a little bit different. Iterating through the customers Dictionary with
a foreach loop, the type returned is KeyValuePair<TKey, TValue>, where TKey is type int and TValue is
type Customer because those are the types that the customersDictionary is defined with.
Since custKeyVal is type KeyValuePair<int, Customer> it has Key and Value properties for you to read from. In our
example, custKeyVal.Keywill
hold
the ID for
the Customer instance
and custKeyVal.Value will
hold
the
whole Customer instance. The parameters in theConsole.WriteLine statement demonstrate this by printing out
the ID, obtained through the Key property, and the Name, obtained through the Name property of
the Customer instance that is returned by the Value property.
The Dictionary type is handy for those situations where you need to keep track of objects via some unique identifier.
For your convenience, here's Listing 20-1, shows how both the List and Dictionary collections work.

Listing 20-1. Introduction to Using Generic Collections with an Example of the


List<T> and Dictionary<TKey, TValue> Generic Collections
using System;
using System.Collections.Generic;
public class Customer
{
public Customer(int id, string name)
{
ID = id;
Name = name;
}
private int m_id;
public int ID
{
get { return m_id; }
set { m_id = value; }
}
private string m_name;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
}

Page 57 of 65

class Program
{
static void Main(string[] args)
{
List<int> myInts = new List<int>();
myInts.Add(1);
myInts.Add(2);
myInts.Add(3);
for (int i = 0; i < myInts.Count; i++)
{
Console.WriteLine("MyInts: {0}", myInts[i]);
}
Dictionary<int, Customer> customers = new Dictionary<int, Customer>();
Customer cust1 = new Customer(1, "Cust 1");
Customer cust2 = new Customer(2, "Cust 2");
Customer cust3 = new Customer(3, "Cust 3");
customers.Add(cust1.ID, cust1);
customers.Add(cust2.ID, cust2);
customers.Add(cust3.ID, cust3);
foreach (KeyValuePair<int, Customer> custKeyVal in customers)
{
Console.WriteLine(
"Customer ID: {0}, Name: {1}",
custKeyVal.Key,
custKeyVal.Value.Name);
}
Console.ReadKey();
}
}
Whenever coding with the generic collections, add a using System.Collections.Generic declaration to
your file, just as in Listing 20-1.

Summary
Generic collections give you the best of all worlds with the strong typing of arrays and flexibility of nongeneric collections. There are many more generic collections to choose from also, such
as Stack, Queue, and SortedDictionary. Look in the System.Collections.Generic namespace for other
generic collections.

07. Methods (Functions)

Methods (C# Programming Guide)


A method is a code block that contains a series of statements. A program causes the statements to be
executed by calling the method and specifying any required method arguments. In C#, every executed
instruction is performed in the context of a method. The Main method is the entry point for every C#
application and it is called by the common language runtime (CLR) when the program is started.

Page 58 of 65

Note

This topic discusses named methods. For information about anonymous functions, see Anonymous
Functions (C# Programming Guide).

Method Signatures
Methods are declared in a class or struct by specifying the access level such as public or private,
optional modifiers such as abstract or sealed, the return value, the name of the method, and any
method parameters. These parts together are the signature of the method.

Note

A return type of a method is not part of the signature of the method for the purposes of method
overloading. However, it is part of the signature of the method when determining the compatibility
between a delegate and the method that it points to.

Method parameters are enclosed in parentheses and are separated by commas. Empty parentheses
indicate that the method requires no parameters. This class contains three methods:
C#
abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }
// Only derived classes can call this.
protected void AddGas(int gallons) { /* Method statements here */ }
// Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* Method statements here */
return 1; }
// Derived classes must implement this.
public abstract double GetTopSpeed();
}

Method Access

Page 59 of 65
Calling a method on an object is like accessing a field. After the object name, add a period, the name of
the method, and parentheses. Arguments are listed within the parentheses, and are separated by
commas. The methods of theMotorcycle class can therefore be called as in the following example:
C#
class TestMotorcycle : Motorcycle
{
public override double GetTopSpeed()
{
return 108.4;
}
static void Main()
{
TestMotorcycle moto = new TestMotorcycle();
moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}

Method Parameters vs. Arguments


The method definition specifies the names and types of any parameters that are required. When calling
code calls the method, it provides concrete values called arguments for each parameter. The arguments
must be compatible with the parameter type but the argument name (if any) used in the calling code
does not have to be the same as the parameter named defined in the method. For example:
C#
public void Caller()
{
int numA = 4;
// Call with an int variable.
int productA = Square(numA);
int numB = 32;
// Call with another int variable.
int productB = Square(numB);
// Call with an integer literal.
int productC = Square(12);
// Call with an expression that evaulates to int.
productC = Square(productA * 3);
}
int Square(int i)

Page 60 of 65
{
// Store input argument in a local variable.
int input = i;
return input * input;
}

Passing by Reference vs. Passing by Value


By default, when a value type is passed to a method, a copy is passed instead of the object itself.
Therefore, changes to the argument have no effect on the original copy in the calling method. You can
pass a value-type by reference by using the ref keyword. For more information, see Passing Value-Type
Parameters (C# Programming Guide). For a list of built-in value types, see Value Types Table (C#
Reference).

When an object of a reference type is passed to a method, a reference to the object is passed. That is,
the method receives not the object itself but an argument that indicates the location of the object. If you
change a member of the object by using this reference, the change is reflected in the argument in the
calling method, even if you pass the object by value.
You create a reference type by using the class keyword, as the following example shows.
C#
public class SampleRefType
{
public int value;
}
Now, if you pass an object that is based on this type to a method, a reference to the object is passed.
The following example passes an object of type SampleRefType to method ModifyObject.
C#

public static void TestRefType()


{
SampleRefType rt = new SampleRefType();
rt.value = 44;
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = 33;
}
The example does essentially the same thing as the previous example in that it passes an argument by
value to a method. But, because a reference type is used, the result is different. The modification that is
made in ModifyObjectto the value field of the parameter, obj, also changes the value field of the
argument, rt, in the TestRefTypemethod. The TestRefType method displays 33 as the output.

Page 61 of 65
For more information about how to pass reference types by reference and by value, see Passing
Reference-Type Parameters (C# Programming Guide) and Reference Types (C# Reference).

Return Values
Methods can return a value to the caller. If the return type, the type listed before the method name, is
not void, the method can return the value by using the return keyword. A statement with
the return keyword followed by a value that matches the return type will return that value to the
method caller. The return keyword also stops the execution of the method. If the return type is void,
a return statement without a value is still useful to stop the execution of the method. Without
the return keyword, the method will stop executing when it reaches the end of the code block. Methods
with a non-void return type are required to use the return keyword to return a value. For example,
these two methods use the return keyword to return integers:
C#
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}
public int SquareANumber(int number)
{
return number * number;
}
}

To use a value returned from a method, the calling method can use the method call itself anywhere a
value of the same type would be sufficient. You can also assign the return value to a variable. For
example, the following two code examples accomplish the same goal:
int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);

Using a local variable, in this case, result, to store a value is optional. It may help the readability of the
code, or it may be necessary if you need to store the original value of the argument for the entire scope
of the method.
For more information, see return (C# Reference).

Page 62 of 65

Async Methods
By using the async feature, you can invoke asynchronous methods without using explicit callbacks or
manually splitting your code across multiple methods or lambda expressions. The async feature was
introduced Visual Studio 2012.

If you mark a method with the async modifier, you can use the await operator in the method. When
control reaches an await expression in the async method, control returns to the caller, and progress in
the method is suspended until the awaited task completes. When the task is complete, execution can
resume in the method.

Note

An async method returns to the caller when either it encounters the first awaited object thats not yet
complete or it gets to the end of the async method, whichever occurs first.

An async method can have a return type of Task<TResult>, Task, or void. The void return type is used
primarily to define event handlers, where a void return type is required. An async method that returns
void can't be awaited, and the caller of a void-returning method can't catch exceptions that the method
throws.

In the following example, DelayAsync is an async method that has a return type
of Task<TResult>. DelayAsync has areturn statement that returns an integer. Therefore the method
declaration of DelayAsync must have a return type of Task<int>. Because the return type
is Task<int>, the evaluation of the await expression in DoSomethingAsyncproduces an integer as the
following statement demonstrates: int result = await delayTask.

The startButton_Click method is an example of an async method that has a return type of void.
BecauseDoSomethingAsync is an async method, the task for the call to DoSomethingAsync must be
awaited, as the following statement shows: await DoSomethingAsync();. The startButton_Click method
must be defined with the asyncmodifier because the method has an await expression.
C#
// using System.Diagnostics;
// using System.Threading.Tasks;
// This Click event is marked with the async modifier.
private async void startButton_Click(object sender, RoutedEventArgs e)

Page 63 of 65
{
await DoSomethingAsync();
}
private async Task DoSomethingAsync()
{
Task<int> delayTask = DelayAsync();
int result = await delayTask;
// The previous two statements may be combined into
// the following statement.
//int result = await DelayAsync();
Debug.WriteLine("Result: " + result);
}
private async Task<int> DelayAsync()
{
await Task.Delay(100);
return 5;
}
// Output:
// Result: 5
An async method can't declare any ref or out parameters, but it can call methods that have such
parameters.
For more information about async methods, see Asynchronous Programming with Async and Await (C#
and Visual Basic), Control Flow in Async Programs (C# and Visual Basic), and Async Return Types (C#
and Visual Basic).

Expression Body Definitions


It is common to have method definitions that simply return immediately with the result of an expression,
or that have a single statement as the body of the method. There is a syntax shortcut for defining such
methods using =>:
C#
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);

Page 64 of 65
If the method returns void or is an async method, then the body of the method must be a statement
expression (same as with lambdas). For properties and indexers, they must be read only, and you do not
use the get accessor keyword.

Iterators
An iterator performs a custom iteration over a collection, such as a list or an array. An iterator uses
the yield returnstatement to return each element one at a time. When a yield return statement is
reached, the current location in code is remembered. Execution is restarted from that location when the
iterator is called the next time.
You call an iterator from client code by using a foreach statement.

The return type of an iterator can be IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>.


For more information, see Iterators (C# and Visual Basic).

08. Debugging in Visual Tools

09. File Controls

10. API

11. Database

12. Programming

13. Application Development

Page 65 of 65

14. Case Study

You might also like