Professional Documents
Culture Documents
Unit 2
C# Application Basics and Language
fundamentals
Creating and compiling C# programs using command line compiler
Let's create our first program using the C# programming language. The program will print a
line of text in a console window. Note that we will be using Console Application as the project
type for the following tutorials. This is just an overview of what you will learn in the following
lessons. I will explain here the structure and syntax of a simple C# program.
Open up Visual Studio. Go to File > New Project to open the New Project Window. You will be
presented with a window asking you of the type and name of the project you want to create.
1
C# Application Basics and Language fundamentals SKNSCOEK
Since we choose Console Application as the project type, we are presented with the Code
Editor.
2
C# Application Basics and Language fundamentals SKNSCOEK
The numbers on the left side are not part of the actual code. They are only there so it will be
easier to reference which code is being discussed by simply telling the line numbers. In Visual
Studio you can go to Tools > Options > Text Editor > C# and then check the Line Numbers
check box to show line numbers in your Visual Studio's code editor. Note that the line
numbers in your code editor may not be aligned with the line numbers in the examples.
Structure of a C# Program
The code in Example 1 is the simplest program you can make in C#. It's purpose is to display
a message to the console screen. Every language has its own basic syntax, which are rules to
follow when writing your code. Let's try to explain what each line of code does.
Line 1 is a namespace declaration, which declares a namespace used as containers for your
codes and for avoiding name collisions. Namespaces will be covered in detail in another
lesson. Right now, the namespace represents the name of your project. Line 2 is an open curly
brace ( { ). Curly braces define a code block. C# is a block-structured language and each block
can contain statements or more valid code blocks. Note that each opening curly brace ( { )
should have a matching closing brace ( } ) at the end. Everything inside the curly braces in
Line 2 and 10 is the code block or body of the namespace.
Line 3 declares a new class. Classes are a topic of object-oriented programming and you will
learn everything about it in later lessons. For now, the codes you write should be contained
inside a class. You can see that it also has its own pair of curly braces (Line 4 and 9), and
everything between them is the class' code block.
Line 5 is called the Main method. A method encapsulates a code and then executes it when
the method is called. Details in creating a method will be explained in a later lesson. The Main
method is the starting point of the program. It means that it is the entry point of execution
and everything inside the Main method are the first ones to execute after all the initializations
have been completed. Picture the Main method as the front door of your house. You will learn
more about the Main method in a later lesson. The Main method and other methods you will
create also has a set of curly braces which defines its code block and inside it are the
statements that will be executed when the method is called.
Statements are commands or operations. Each statement must end with a semicolon (;).
Forgetting to add the semicolon will result in a syntax error. Statements are located inside
code blocks. An example of a statement is the following code (Line 7):
System.Console.WriteLine("Welcome to Visual C# Tutorials!");
This is the code that displays the message "Welcome to Visual C# Tutorials!". We need to use
the WriteLine() method and pass the string message inside it. A string or string literal is a
group of characters and they are enclosed in double quotes ("). A character is any letter,
number, symbol, or punctuation. For now, the whole line simply means "Use the WriteLine
3
C# Application Basics and Language fundamentals SKNSCOEK
method located in the Console class which is located in the System namespace". More of these
will be explained in the upcoming lessons.
C# ignores spaces and new lines. Therefore, you can write the same program in Example 1 in
just one line. But that will make your code extremely hard to read and debug. Also,
statements can span multiple lines as long as you terminate the last line with a
semicolon. One common error in programming is adding semicolons at every end of a line
even though multiple lines represent a single statement. Consider the following example.
System.Console.WriteLine(
"Welcome to Visual C# Tutorials!");
4
C# Application Basics and Language fundamentals SKNSCOEK
You can make additional customizations to Visual Studio, such as changing the font face
and size of the text in the editor or the color theme of the IDE, by using the Options dialog
box. Depending on the settings combination that you’ve applied, some items in that dialog
box might not appear automatically. You can make sure that all possible options appear by
choosing the Show all settings check box.
Figure 3: Options dialog box
In this example, you’ll change the color theme of the IDE from light to dark. You can skip
ahead to create a project if you like.
5
C# Application Basics and Language fundamentals SKNSCOEK
6
C# Application Basics and Language fundamentals SKNSCOEK
The color theme used for pictures in the rest of this walkthrough is the light theme. For
more information about customizing the IDE, see Customizing Development Settings in
Visual Studio.
Create a simple application
When you create an application in Visual Studio, you first create a project and a solution.
For this example, you’ll create a Windows Presentation Foundation (WPF) project.
To create the WPF project
1. Create a new project. On the menu bar, choose File, New, Project….
You can also type New Project in the Quick Launch box to do the same thing.
2. Choose the Visual Basic or the Visual C# WPF Application template by choosing in
the left pane Installed, Templates, Visual C#, Windows, for example, and then
choosing WPF Application in the middle pane. Name the project HelloWPFApp at the
bottom of the New Project dialog.
7
C# Application Basics and Language fundamentals SKNSCOEK
Visual Studio creates the HelloWPFApp project and solution, and the Solution
Explorer shows the various files. The WPF Designer shows a design view and an XAML view
of MainWindow.xaml in a split view. You can slide the splitter to show more or less of either
view. You can choose to see only the visual view or only the XAML view. (For more
information, see WPF Designer for Windows Forms Developers). The following items appear
in Solution Explorer:
Figure 5: Project items
After you create the project, you can customize it. By using the Properties window (found
on the View menu), you can display and change options for project items, controls, and
other items in an application. By using the project properties and property pages, you can
display and change options for projects and solutions.
To change the name of MainWindow.xaml
1. In the following procedure, you’ll give MainWindow a more specific name.
In Solution Explorer, select MainWindow.xaml. You should see
the Properties window, but if you don’t, choose the View menu and the Property
Window item. Change the File Name property to Greetings.xaml.
8
C# Application Basics and Language fundamentals SKNSCOEK
Solution Explorer shows that the name of the file is now Greetings.xaml, and if you
expand the MainWindow.xaml node (by putting focus in the node and pressing the
rightarrow key), you see the name of MainWindow.xaml.vb or MainWindow.xaml.cs
is now Greetings.xaml.vb or Greetings.xaml.cs. This code file is nested under the
.xaml file node to show they are very closely related to each ot
9
C# Application Basics and Language fundamentals SKNSCOEK
Or you can simply hit Ctrl + Shift + A. Whichever way you choose, a dialog will be presented
to you asking you to choose which file you are trying to create.
Choose the Class template and name it Sample.cs. C# code files have file extensions of cs. For
the purpose of this lesson, delete all the contents that are provided to you after creating the
class and write the following code.
namespace MyNamespace
10
C# Application Basics and Language fundamentals SKNSCOEK
{
class Sample
{
public void ShowMessage()
{
System.Console.WriteLine("Hello World!");
}
}
Here, we defined our namespace and named it MyNamespace. Inside it is our class Sample
with one method that shows a message. Take note that we accessed the
Console.WriteLine() method by calling the System namespace and by using the dot syntax.
You can use the using keyword to allow you to omit the System namespace when calling
the Console.WriteLine() method. Now switch to Program.cs which is the default file when you
created the project earlier. Delete the contents and write the following code.
using MyNamespace;
class Program
{
static void Main()
{
Sample test = new Sample();
test.ShowMessage();
}
}
Hello World!
We use the using keyword to import all the contents of the MyNamespace which is the
namespace that we created. If we are to remove that statement, then we should precede
the Sample with MyNamespace every time we want to use it.
MyNamespace.Sample test = new MyNamespace.Sample();
You can add multiple classes or interface inside a namespace. They will all be contained
inside that namespace.
namespace MyNamespace
{
class Sample1
{
}
class Sample2
{
}
}
You are not limited to packaging your class into just one namespace. You can nest your
namespace to further categorize your codes.
namespace MyNamespace1
{
namespace MyNamespace2
{
class Sample
{
public void ShowMessage()
11
C# Application Basics and Language fundamentals SKNSCOEK
{
System.Console.WriteLine("Hello World!");
}
}
}
}
To access the Sample class, you have to indicate first all the namespaces that wrap it.
MyNamespace1.MyNamespace2.Sample
Or you can use again the using statement.
using MyNamespace1.MyNamespace2;
The .NET Framework itself consist of deep and nested namespaces. For example,
the System.Data.SqlClient are three namespaces nested together. The .NET Framework uses
namespaces to categorize each of the technologies it supports.
You can create an alias namespace if you want to make nested namespaces to smaller or
easier to type.
using AliasNamespace = MyNamespace1.MyNamespace2;
Value types
Reference types
Pointer types
Value Type
Value type variables can be assigned a value directly. They are derived from the
class System.ValueType.
The value types directly contain data. Some examples are int, char, and float, which stores
numbers, alphabets, and floating point numbers, respectively. When you declare
an int type, the system allocates memory to store the value.
The following table lists the available value types in C# 2010:
Type Represents Range Default
Value
decimal 128-bit precise decimal (-7.9 x 1028 to 7.9 x 1028) / 100 to 28 0.0M
values with 28-29
significant digits
12
C# Application Basics and Language fundamentals SKNSCOEK
To get the exact size of a type or a variable on a particular platform, you can use
the sizeof method. The expression sizeof(type) yields the storage size of the object or type in
bytes. Following is an example to get the size of int type on any machine:
Reference Type
The reference types do not contain the actual data stored in a variable, but they contain a
reference to the variables.
In other words, they refer to a memory location. Using multiple variables, the reference types
can refer to a memory location. If the data in the memory location is changed by one of the
variables, the other variable automatically reflects this change in value. Example of built-
in reference types are: object, dynamic, and string.
Object Type
The Object Type is the ultimate base class for all data types in C# Common Type System
(CTS). Object is an alias for System.Object class. The object types can be assigned values of
any other types, value types, reference types, predefined or user-defined types. However,
before assigning values, it needs type conversion.
When a value type is converted to object type, it is called boxing and on the other hand,
when an object type is converted to a value type, it is called unboxing.
object obj;
obj = 100; // this is boxing
Dynamic Type
You can store any type of value in the dynamic data type variable. Type checking for these
types of variables takes place at run-time.
13
C# Application Basics and Language fundamentals SKNSCOEK
String Type
The String Type allows you to assign any string values to a variable. The string type is an
alias for the System.String class. It is derived from object type. The value for a string type
can be assigned using string literals in two forms: quoted and @quoted.
For example,
String str = "Tutorials Point";
A @quoted string literal looks as follows:
@"Tutorials Point";
The user-defined reference types are: class, interface, or delegate. We will discuss these types
in later chapter.
Pointer Type
Pointer type variables store the memory address of another type. Pointers in C# have the
same capabilities as the pointers in C or C++.
Syntax for declaring a pointer type is:
type* identifier;
For example,
char* cptr;
int* iptr;
Operators
An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. C# has rich set of built-in operators and provides the following type of
operators:
Arithmetic Operators
Relational Operators
Logical Operators
Bitwise Operators
Assignment Operators
Misc Operators
This tutorial explains the arithmetic, relational, logical, bitwise, assignment, and other
operators one by one.
Arithmetic Operators
14
C# Application Basics and Language fundamentals SKNSCOEK
Following table shows all the arithmetic operators supported by C#. Assume variable A holds
10 and variable B holds 20 then:
Show Examples
Operator Description Example
Relational Operators
Following table shows all the relational operators supported by C#. Assume variable A holds
10 and variable B holds 20, then:
Show Examples
Operator Description Example
== Checks if the values of two operands are equal or not, if yes then (A == B)
condition becomes true. is not
true.
> Checks if the value of left operand is greater than the value of (A > B) is
right operand, if yes then condition becomes true. not true.
< Checks if the value of left operand is less than the value of right (A < B) is
operand, if yes then condition becomes true. true.
>= Checks if the value of left operand is greater than or equal to the (A >= B)
value of right operand, if yes then condition becomes true. is not
true.
<= Checks if the value of left operand is less than or equal to the (A <= B)
value of right operand, if yes then condition becomes true. is true.
Logical Operators
Following table shows all the logical operators supported by C#. Assume variable A holds
Boolean value true and variable B holds Boolean value false, then:
Show Examples
Operator Description Example
15
C# Application Basics and Language fundamentals SKNSCOEK
&& Called Logical AND operator. If both the operands are non zero (A && B)
then condition becomes true. is false.
! Called Logical NOT Operator. Use to reverses the logical state of !(A &&
its operand. If a condition is true then Logical NOT operator will B) is
make false. true.
Bitwise Operators
Bitwise operator works on bits and perform bit by bit operation. The truth tables for &, |,
and ^ are as follows:
p q p&q p|q p^q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
Assume if A = 60; and B = 13; then in the binary format they are as follows:
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
The Bitwise operators supported by C# are listed in the following table. Assume variable A
holds 60 and variable B holds 13, then:
Show Examples
Operator Description Example
& Binary AND Operator copies a bit to the result if it exists in (A & B) =
both operands. 12, which is
0000 1100
16
C# Application Basics and Language fundamentals SKNSCOEK
~ Binary Ones Complement Operator is unary and has the effect (~A ) = 61,
of 'flipping' bits. which is
1100 0011
in 2's
complement
due to a
signed
binary
number.
<< Binary Left Shift Operator. The left operands value is moved A << 2 =
left by the number of bits specified by the right operand. 240, which
is 1111
0000
>> Binary Right Shift Operator. The left operands value is moved A >> 2 = 15,
right by the number of bits specified by the right operand. which is
0000 1111
Assignment Operators
There are following assignment operators supported by C#:
Show Examples
Operator Description Example
17
C# Application Basics and Language fundamentals SKNSCOEK
Miscellaneous Operators
There are few other important operators including sizeof, typeof and ? :supported by C#.
Show Examples
Operator Description Example
as Cast without raising an exception if the cast fails. Object obj = new
StringReader("Hello");
StringReader r = obj as
StringReader;
Operator Precedence in C#
Operator precedence determines the grouping of terms in an expression. This affects
evaluation of an expression. Certain operators have higher precedence than others; for
example, the multiplication operator has higher precedence than the addition operator.
18
C# Application Basics and Language fundamentals SKNSCOEK
For example x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher
precedence than +, so the first evaluation takes place for 3*2 and then 7 is added into it.
Here, operators with the highest precedence appear at the top of the table, those with the
lowest appear at the bottom. Within an expression, higher precedence operators are
evaluated first.
Show Examples
Category Operator Associativity
19
C# Application Basics and Language fundamentals SKNSCOEK
C# provides following types of decision making statements. Click the following links to check
their detail.
Statement Description
The ? : Operator:
We have covered conditional operator ? : in previous chapter which can be used to
replace if...else statements. It has the following general form:
Exp1 ? Exp2 : Exp3;
Where Exp1, Exp2, and Exp3 are expressions. Notice the use and placement of the colon.
The value of a ? expression is determined as follows: Exp1 is evaluated. If it is true, then
Exp2 is evaluated and becomes the value of the entire ? expression. If Exp1 is false, then
Exp3 is evaluated and its value becomes the value of the expression.
Looping
Looping allows you to repeat a set of code or statements while a given condition is true.
Without it, you have to write multiple similar codes just to make your program repeat and
that is tedious. Suppose you want to print "Hello World." 10 times. It will look like this
without using a loop.
Console.WriteLine("Hello World.");
Console.WriteLine("Hello World.");
Console.WriteLine("Hello World.");
Console.WriteLine("Hello World.");
Console.WriteLine("Hello World.");
Console.WriteLine("Hello World.");
Console.WriteLine("Hello World.");
Of course, you can copy the first line and just hit Ctrl + V to paste the other nine, but what
I'm trying to show you here is inefficiency. There is a way to better write all of these lines of
code and that's by using a loop. There are different kinds of looping structure in C#.
while Loop
do while Loop
20
C# Application Basics and Language fundamentals SKNSCOEK
for Loop
Arrays
An array is a kind of variable that stores a list of addresses of variables and can store
a set of data having the same data type. Declaring multiple variables with the same
type and used for the same purpose can be exhausting. What if you want to store a
thousand values with integers and they will be used, for example, a list of grades of
students. It would be tedious to declare all of those one thousand variables. But with
arrays, you can declare them in one line. Below shows you the simplest way to declare
an array.
datatype[] arrayName = new datatype[length];
The datatype is the type of variable that the array will store. The square brackets next
to the data type tell that it is an array. The arrayName is the identifier or the name of
the variable. When naming an array, it is a good practice to make it plural to indicate
that it is an array. For example, use numbers instead of number when naming an
array. The length tells the compiler how many data or values you are going to store in
an array. We used the new keyword to allocate enough spaces for the array in the
memory depending on the value specified by the length. Each item in an array is
called an array element. If we are to declare an array that can store 5 values of type
integer, we would write:
int[] numbers = new int[5];
This declaration reserves 5 addresses inside your computer's memory waiting for a
value to be stored. So how can we store values to each of the array elements? Array's
value can be accessed and modified by indicating their index or position.
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
Index starts with 0 and ends with (length - 1) of the array. For example, we have 5
elements so the indices of our array start from 0 and ends with 4 because length - 1
equates to 5 - 1 which is 4. That means that index 0 is the first element, index 1 is the
second element and so on. Look at the image below to better understand this concept.
Figure 1
21
C# Application Basics and Language fundamentals SKNSCOEK
Consider each square is an array element and the values inside them are the values they
contain. Newbie programmers often get confused by the index resulting to errors such as
starting the count from 1 to 5. If you access an array element with an index that's not
inside the range of valid indexes, then you will get an IndexOutOfRangeException which
simply says that you are accessing an address that does not exist. Just remember the
formula and you won't have any problems.
If you want to assign values immediately in the declaration of a variable, you can do a
modified version of the declaration of an array.
datatype[] arrayName = new datatype[length] { val1, val2, ... valN };
You can enumerate the values inside curly braces immediately after the declaration of
the size of the array. You should separate the values with commas. The number of
values inside the curly braces should exactly match the size of the array declared.
Let's look at an example.
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
This will have the same results as the code in Figure 1 but it save us a lot of lines of
code. You can still change the values of any element by accessing its index and
assigning a new value. Our numbers array requires 5 elements so we supplied it with
5 values. If we are to supply less or more than it requires, we will encounter an error.
There is another way of declaring an array. You can supply an array with any number
of values as long as you do not indicate the size. Here's an example:
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
We are now giving 10 values to the array. Notice that there's no length indicated for
the array. If this is the case, the compiler will count the number of values inside the
curly braces and that will determine the length of the array. Note that if you do not
give a length for the array, you need to supply values for it. If not, you will receive an
error.
int[] numbers = new int[]; //not allowed
There is a shorter version for doing this:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
We simply assign the values inside curly braces without using the new keyword and
the data type. This will also assign all of the 10 values into the array and automatically
counts the length that the array should have.
Accessing Array Values Using for Loop
The following is an example of using arrays. Our program will retrieve 5 values from
the user and then calculate the average of those numbers.
Example 1 - Using Arrays
Line 9 declares an array that can hold 5 integer values. Lines 10 and 11 declares
variables that will be used on calculating the average. Note that total is initialized to 0
to avoid errors when adding values to it. Lines 13-17 uses a for loop that will repeat
22
C# Application Basics and Language fundamentals SKNSCOEK
on getting input from the user. We used the Length property of the array to determine
the number of elements it contains. Although we can simply specify the value 5 in the
condition, using the Length property is more versatile as we can change the length of
the array and the condition in the for loop will adjust to the new change. Line 16
retrieves input from the user, converts it to int, and stores it on an array element.
The index uses the current value of i. For example, at the beginning of the loop, i is
initialized to 0, so when Line 16 is first encountered, it will add the value retrieve by
the user to numbers[0]. After the loop, i is incremented by 1, and one Line 16 is
reached again, it will now assign the retrieved value to numbers[1]. It will continue as
long as the for loop meets the condition.
using System;
namespace ClassesDemo
{
public class Person
{
23
C# Application Basics and Language fundamentals SKNSCOEK
firstPerson.name = "Jack";
firstPerson.age = 21;
firstPerson.height = 160;
firstPerson.TellInformation();
Console.WriteLine(); //Separator
secondPerson.name = "Mike";
secondPerson.age = 23;
secondPerson.height = 158;
secondPerson.TellInformation();
}
}
}
Example 1 - Your First Class
Name: Jack
Age: 21 years old
Height: 160cm
Name: Mike
Age: 23 years old
Height: 158cm
The program above contains two classes, the Person class and the Program class.
We know that the Program class contains the Main() method which is required in
a program so let's focus our attention on the Person class.
Lines 5-17 is the declaration of our Person class. Line 5 specifies the name of the
class and its accessibility. We used the public access specifier so other classes
can recognize the Person class. We'll take a look at access specifiers in a separate
lesson. Inside the body of the class are fields for that class (lines 7-9). We defined
three fields that resemble the real properties of a real-world person. A person has
a name, age, and height. Lines 11-16 defined one method inside the class
named TellInformation(). It is the behavior of our class as if we are asking
the Person object to tell something about himself. Inside the method are codes
that will display the currently stored values of the fields. You can see that it
24
C# Application Basics and Language fundamentals SKNSCOEK
simply shows the values of the class' fields. One thing to note about fields. Since
they are declared inside the class and considered as class members, they have a
class scope. It means that these fields can only be used inside the class where it
belongs or by an instance of a class.
Constructors
Constructors are special methods that are required to create or "construct" objects.
They allow you to assign the initial values for each data member of an array and add
codes that you want to execute when you create an object. If you don't include any
constructors in a class, then the compiler will use a default constructor which is a
constructor that has no parameters. You can have as many constructors as you want
provided that they have a different set of parameters. Let's take a look at a class that
contains a constructor.
The program in Example 1 is the same program that we saw in the last lesson. We
added two constructors for class Person. One is the default constructor (lines 12-
14) and the other is a constructor that accepts three arguments (lines 17-22).You
notice that a constructor is just like a method, but it must not have a return type,
not even void. The name of a constructor must exactly match with the name of
the class. The default constructor has nothing inside its body. This is the same as
the default constructor being called if we did not provide any constructors for a
class. We will see later how we can assign default values to data members when
using a default constructor. Take a look at the second constructor. It has the
same name as the first one. Constructors can be overloaded like methods. Let's
look at how we can call a specific constructor based on the declaration of the
instances of the class.
Person firstPerson = new Person();
Person secondPerson = new Person("Mike", 23, 158);
On the first instance of person, we used the default constructor because there are
no arguments inside the parentheses. On the second declaration, we are now
using the second constructor because the three arguments that the parameter of
the constructor is expecting are provided. The code below shows the effect of using
two different constructors.
firstPerson.name = "Jack";
firstPerson.age = 21;
firstPerson.height = 160;
firstPerson.ShowInformation();
Console.WriteLine(); //Seperator
secondPerson.ShowInformation();
25
C# Application Basics and Language fundamentals SKNSCOEK
As you can see, the object that used the default constructor requires you to assign
the values for it data members so it can show something if you call
the ShowInformation() method. Contrast to the second object that used the
parameterized constructor, you just call the method and everything will run as
expected. This is because, you already gave the values for the data members when
you declared the instance so there's no need to reassign values unless you want to
modify the value of a data member.
Providing Default Values for the Default Constructor
The program in Example 1 showed a default constructor that has an empty body.
You can add codes inside the default constructor. You can assign default values to
the data members if nothing is provided by the user.
public Person()
{
name = "No Name";
age = 0;
height = 0;
}
Now our default constructor has something to do. If we declared an instance that
uses this constructor, then it will be assigned the default values.
Person person1 = new Person();
person1.ShowInformation();
Name: No Name
Age: 0 years old
Height: 0cm
Using the this Keyword
Another way of providing default values is by using the this keyword. The example
below shows a modified program in Figure1 and uses 4 constructors with
different number of parameters.
using System;
namespace ConstructorDemo2
{
public class Person
{
public string name;
public int age;
public double height;
public Person()
: this("No Name", 0, 0)
{
}
public Person(string n)
: this(n, 0, 0)
{
}
26
C# Application Basics and Language fundamentals SKNSCOEK
{
}
firstPerson.ShowInformation();
secondPerson.ShowInformation();
thirdPerson.ShowInformation();
fourthPerson.ShowInformation();
}
}
}
Example 2 - Using the this Keyword
27
C# Application Basics and Language fundamentals SKNSCOEK
terms parameters and arguments are used interchangeably. The basic syntax of the
simplest method is as follows.
returnType MethodName()
{
code to execute;
}
Let's look at an example program that uses a simple method that prints a message in the
screen.
using System;
namespace MethodsDemo
{
public class Program
{
static void PrintMessage()
{
Console.WriteLine("Hello World!");
}
public static void Main()
{
PrintMessage();
}
}
}
Example 1 - Your First Method
Hello World!
In lines 7-10, we declared our first method. The position inside the class is not important. For
example, you can place it below the Main() method instead. You can call (or invoke) this
method inside other methods. Write now, we only have Main() as the other method who can
possible call PrintMessage(). You can see that the Main() method is declared as static. For the
PrintMessage() method to be used by the Main() method, it needs to be static also.
Properties
Properties are the C# standard for accessing private data members inside a class. They may
behave like normal fields, but properties have getters which gets the value of the private data
and setters which sets a value to a private data. Getters and setters can directly retrieve and
assign values to a private field or you can write custom code inside those to customize the
behavior of retrieval and assignment to a field. Properties are typically public as they are
usually consumed from the outside of the class. The example below shows how to define and
use properties.
using System;
namespace PropertiesDemo
{
public class Person
{
private string name;
private int age;
private double height;
28
C# Application Basics and Language fundamentals SKNSCOEK
Console.WriteLine(); //Seperator
29
C# Application Basics and Language fundamentals SKNSCOEK
person1.Name = "Frank";
person1.Age = 19;
person1.Height = 162;
person2.Name = "Ronald";
person2.Age = 25;
person2.Height = 174;
Console.WriteLine(); //Seperator
Console.WriteLine();
Name: Mike
Age: 23 years old
Height: 158cm
Name: Frank
Age: 19 years old
Height: 162cm
Name: Ronald
Age: 25 years old
Height: 174cm
The program introduces the use of properties and we defined three properties which
correspond to each of the data members.
private string name;
private int age;
private double height;
These fields are also called backing fields of the properties. Notice that we made our data
members private to promote encapsulation. Their values can only be accessed through the
provided properties.
public string Name
{
get
{
return name;
}
30
C# Application Basics and Language fundamentals SKNSCOEK
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public double Height
{
get
{
return height;
}
set
{
height = value;
}
}
These are the properties. When writing a property, we indicate its accessibility which is public
and we provide the data type which is the data type of the value it will return or accept. Notice
that the name of the properties are the same as their corresponding data members except that
the first letter is capitalized. It doesn't have to, but that is another convention in C#. Inside
the body, you see getters and setters. The getter, indicated by the get keyword, allows you to
extract the data from a private data member. The setters, indicated by the set keyword allows
you to set a value to a data member. Notice the value keyword inside the setter. The value
contains what is being assigned to the property.
To access a property, you simply use the dot syntax.
Console.WriteLine("Name: {0}", person1.Name);
Console.WriteLine("Age: {0} years old", person1.Age);
Console.WriteLine("Height: {0}cm", person1.Height));
Calling a property this way will execute the code inside the body of the getter of the specified
property. The getter then returns the value to the caller just like a method. Setting value to a
property is also very simple.
person1.Name = "Frank";
person1.Age = 19;
person1.Height = 162;
The statements above calls the setter of each of those properties which assign the value to the
corresponding data members.
Using properties is very flexible especially you want to add validation when getting or setting
data to the members of the object. For example, you can add a restriction that only positive
31
C# Application Basics and Language fundamentals SKNSCOEK
number can be assigned to the age of the person. You can modify the setter of the Age
property like this:
public int Age
{
get
{
return age;
}
set
{
if (value > 0)
age = value;
else
age = 0;
}
}
This time, if a user tries to assign a negative number to the age of the person, it will assign 0
instead because of the if statement inside the setter of the property.
You can also make a property read-only (cannot be set with values) by not including a setter.
For example, you can make the Name property read-only by doing the following:
public string Name
{
get
{
return name;
}
}
When you try to assign a new value to name, then an error will occur. Another thing is that
you can also place access specifiers for getters and setters. Consider the following code:
public string Name
{
get
{
return name;
}
private set
{
name = value;
}
}
The Name property can only be read outside the class, but only methods inside the Person
class can set new values.
A property doesn't need to be associated to one private data member. It can be a combination
of two data. Consider the code below.
private string firstName;
private string lastName;
public FullName
{
get { return firstName + " " + lastName; }
}
32
C# Application Basics and Language fundamentals SKNSCOEK
We defined a read-only property called FullName which returns the combination of firstName
and lastName separated by a space.
Automatic Properties
C# also offers a shortcut when creating properties. You can define a property without any
private data member associated with it.
public int MyProperty { get; set; }
This feature is also called automatic properties which were introduced in C# 3.0. Notice that
we didn't supply any code for the getter and setter. The above statement is equivalent to
defining a private int data member and it's corresponding property except that the shorthand
version is done in one line. This is automatically recognized by the compiler as a property and
a corresponding backing field is created during runtime. Note that when defining automatic
properties, you must have both the getter and the setter. You also cannot put codes inside the
getter or setter of an automatic property.
Auto-Property Initializer
A new feature in C# 6 called auto-property initializers allows us to initialize values of
automatic properties. The initial value will be assigned to the underlying backing field of the
automatic property. You cannot use auto-property initializer on non-automatic properties (as
the name implies). Here is an example of using auto-property initializer.
public class Person
{
public string FirstName { get; set; } = "FirstName";
namespace AccessSpecifiersDemo
{
public class Test
{
public int number;
}
33
C# Application Basics and Language fundamentals SKNSCOEK
x.number = 10;
}
}
}
Example 1 - public Access Specifier
We declared our test class as public. This will allow the Program class to create Test
instances. We also declared one public data member inside the Test class. We tested if we can
access that data member from outside the Test class by assigning a value to it inside
the Main() method of the Program class. If we are to omit the use of the public keyword, then
we won't be able to create a Test class and access its data member. That is similar to the
private access specifier.
using System;
namespace AccessSpecifiersDemo2
{
private class Test
{
public int number;
}
x.number = 10;
}
}
}
Example 2 - private Access Specifier
We used the private keyword for class Test. Compiling this will produce an error because Test
now can't be accessed anywhere inside the Program class or any other classes. Note that even
though the data member of the Test class is public, it cannot be accessed because the class
itself is private which makes everything inside it inaccessible.
Note that if you don't specify any access specifier for a class, it will use internal access
specifier which means that only the classes within the current project can access the class.
Using internal is equivalent to public but it can't be accessed outside the project. The
following code has the same in effect.
class Test
{
}
internal class Test
34
C# Application Basics and Language fundamentals SKNSCOEK
{
}
If we made our class public but its data member is private, then we can create an instance of
that class outside of it but the private data member cannot be accessed. The private data
member can only be accessed by methods within the Test class.
using System;
namespace AccessSpecifiDemo3
{
public class Test
{
private int number;
}
namespace StaticMembersDemo
{
class SampleClass
{
public static string StaticMessage { get; set; }
public string NormalMessage { get; set; }
35
C# Application Basics and Language fundamentals SKNSCOEK
class Program
{
public static void Main()
{
SampleClass sample1 = new SampleClass();
SampleClass sample2 = new SampleClass();
36
C# Application Basics and Language fundamentals SKNSCOEK
static method, you cannot use any properties, fields or methods that are not labeled as
static.
private int number = 10;
display.WriteLine("My message!");
We will need to create an instance of the Console class first before we can display messages.
Another thing to note is the Main() method declared as static. The compiler requires it to be
static so it can be executed in a program without creating an instance of it.
Structures
Structures or structs are user-defined data types that can contain other variables as
its fields and methods as its behavior. You can create your very own customized data type
using structures. Let say you want a data that don't just store a name as a string, but you
also want to include his age and his monthly salary. To define a structure in a program, we
use the following syntax.
struct StructName
{
member1;
member2;
member3;
...
member4;
}
We declare a structure using the struct keyword. Names of structures should used Pascal
Casing to indicate that it is a structure, but that is just a convention followed in C#
programming. The members can either be variables or methods. The program below shows an
example of a structure.
using System;
namespace StructuresDemo
{
public struct Employee
{
public string name;
public int age;
public decimal salary;
}
37
C# Application Basics and Language fundamentals SKNSCOEK
employee1.name = "Jack";
employee1.age = 21;
employee1.salary = 1000;
employee2.name = "Mark";
employee2.age = 23;
employee2.salary = 800;
Console.WriteLine("Employee 1 Details");
Console.WriteLine("Name: {0}", employee1.name);
Console.WriteLine("Age: {0}", employee1.age);
Console.WriteLine("Salary: {0:C}", employee1.salary);
Console.WriteLine(); //Seperator
Console.WriteLine("Employee 2 Details");
Console.WriteLine("Name: {0}", employee2.name);
Console.WriteLine("Age: {0}", employee2.age);
Console.WriteLine("Salary: {0:C}", employee2.salary);
}
}
}
Example 1 - Using Structures
Employee 1 Details
Name: Jack
Age: 21
Salary: $1000.00
Employee 2 Datails
Name: Mike
Age: 23
Salary: $800.00
Let's dissect the code to better understand the program. Lines 5-10 is the declaration of a
structure. Note that we used the public keyword. That keyword simply indicates that our
Employee can be accessed or used anywhere in the program (or outside the program). public
is one of the access specifiers and will be discussed in greater detail in later lessons. We used
the struct keyword followed by the name of the structure. Structure names also follow the
Pascal Casing convention. Inside the body of the structure, we defined three fields. Fields are
like the properties of our Employee. For example, an employee has a name, an age and for he
to continue his job, he is given a monthly salary. These members were also declared as public
so they can be called outside the structure as demonstrated later.
Lines 16 and 17 declares two instances of Employee. The declaration of structure instances is
similar to normal variables. You first indicate the structure type, and then the identifier.
38
C# Application Basics and Language fundamentals SKNSCOEK
Lines 19 to 25 assigned values to the respective fields of each employee. To access the fields
outside the structure, they must be public first (or internal as seen in a later lesson). We first
write the name of the variable, followed by a dot (.) and then the name of the field. When the
dot operators is used in this context, it is called the member access operator as it allows you
to call the members of a particular structure (and class as we will see in the following
lessons).
Lines 27 to 37 demonstrates how you can access the values stored on each field of a
structure variable. When accessing or reading a field, we do the same thing. We indicate the
variable name followed by a dot and then the name of the field to be read.
Structures are value types. That means that if we assign employee2 with a value of
employee1, employee2 will copy all the values of the attributes of employee1 instead of getting
its reference. A class is similar to a structure but it is a reference type. It will be discussed in
a later lesson.
You can also add methods inside a structure. The example below modifies the program in
Example 1.
using System;
namespace StructuresDemo2
{
public struct Employee
{
public string name;
public int age;
public decimal salary;
employee1.name = "Jack";
employee1.age = 21;
employee1.salary = 1000;
employee2.name = "Mark";
employee2.age = 23;
employee2.salary = 800;
Console.WriteLine("Employee 1 Details");
Console.WriteLine("Name: {0}", employee1.name);
Console.WriteLine("Age: {0}", employee1.age);
Console.WriteLine("Salary: {0:C}", employee1.salary);
39
C# Application Basics and Language fundamentals SKNSCOEK
employee1.SayThanks();
Console.WriteLine(); //Seperator
Console.WriteLine("Employee 2 Details");
Console.WriteLine("Name: {0}", employee2.name);
Console.WriteLine("Age: {0}", employee2.age);
Console.WriteLine("Salary: {0:C}", employee2.salary);
employee2.SayThanks();
}
}
}
Example 2 - Using Structures
Employee 1 Details
Name: Jack
Age: 21
Salary: $1000.00
Jack thanked you!
Employee 2 Details
Name: Mike
Age: 23
Salary: $800.00
Mike thanked you!
Lines 11 to 14 define a new method inside a structure. This method prints a message and gets
the value of the name field to show a unique message for each instance. To call the method,
we used similar syntax except that instead of the field following the dot, we indicate the name
of method to call followed by parentheses—and a set of arguments if they are required by a
function.
class MyClass
{
public string Message { get; set; }
}
40
C# Application Basics and Language fundamentals SKNSCOEK
class Program
{
static void Main()
{
MyStructure structure1 = new MyStructure();
MyStructure structure2 = new MyStructure();
structure1.Message = "ABC";
structure2 = structure1;
class1.Message = "ABC";
class2 = class1;
41
C# Application Basics and Language fundamentals SKNSCOEK
We made a structure and a class that we will use to demonstrate their differences. We
provided a Message property for each of the two. We then create two instances for each of
them. We assigned a value for the Message property of structure1. We then assign the value
of structure1 to structure2 so everything inside structure1 will be copied to structure2. To
prove that everything was copied from structure1, we showed the value of
structure2's Message property and you can see that it is the same as the
structure1's Message property value. To show that structures are value types, we assigned
another message to the Message property of structure2. The Message property of structure1
is not affected because the structure2 is a separate copy of structure1.
Now to demonstrate the behavior of reference types and classes. Classes pass their address
and not their value when they're being assigned to other variables. Therefore, when you edit
a property of the object that receive the address of the original object, the property of that
original object is also modified. When you're passing an object as an argument to a method,
only the address of that object is passed. Any modifications to that object inside that
method will also reflect the original object that passed its address.
String Manupalation
The string in C# is handled by the System.String class. Before you can create and use
strings, you must import the System namespace. There are multiple ways to create a string.
String str1;
str1 = "An example of a string.";
Notice that a string is enclosed in double quotation marks ("). This indicates to the compiler
that the data you are storing to the variable is a string.
The System.String class is mapped to the string keyword thanks to CTS. This allows you to
use the keyword string, instead of the class System.String when creating a string.
string myString;
myString = "An example of a string.";
You can declare a string and assign it a value in one statement, like this:
string myString = "This is another string";
You can also use the new keyword and the System.String constructor to assign value to the
string.
String myString = new String("This is a string.");
string myString = new string("This is a string");
In .NET, a string is a reference type but behaves very much like a value type. Consider the
following example of a typical reference type:
Button btn1 = new Button();
btn1.Text = "Button 1 ";
Button btn2 = btn1; // Assign address of btn1 to btn2
42
C# Application Basics and Language fundamentals SKNSCOEK
Console.WriteLine(btn1.Text);
Console.WriteLine(btn2.Text);
Button 1 and Button 2
Button 1 and Button 2
We created a Button named btn1 and assign the Text property with a string. Next, we
assigned the reference of btn1 to another Button named btn2. They are now referring to the
same button. We now modify the Text property of btn2 by concatenating (combining) another
string. Note that btn2.Text contains the Text from btn1 because they are referring to the same
button. After the modification, we output the contains of the Text for each button. The result
is the same. The moment that we modified the Text of btn2, the Text of btn1 was modified as
well. (It is evident in the output of the WriteLine() statements).
If strings are indeed reference types, then the same behavior can be expected with the
following code:
string str1 = "String 1";
string str2 = str1;
Now, str1 and str2 should now be pointing to the same instance. If we modify the value of
str2, then str1 should be modified as well.
str2 += " and String 2";
Let's print the values of the strings.
Console.WriteLine(str1);
Console.WriteLine(str2);
String 1
String 1 and String 2.
You can see that the values are different. The value of str1 was copied to str2. They do not
point on the same instance. Therefore, changes you make with str2 will not reflect str1. A
string can't be a value type because it can handle a value an unpredictable length of
characters.
A string is basically a collection of Unicode characters. The following code shows this by
splitting each character using a foreach loop.
string str1 = "This is a string";
foreach (char c in str1)
{
Console.WriteLine(c);
}
char[] charArray = { 'H', 'e', 'l', 'l', 'o' };
Naming Conventions
43
C# Application Basics and Language fundamentals SKNSCOEK
This section describes general naming conventions that relate to word choice, guidelines on
using abbreviations and acronyms, and recommendations on how to avoid using language-
specific names.
Word Choice
X AVOID using identifiers that conflict with keywords of widely used programming
languages.
According to Rule 4 of the Common Language Specification (CLS), all compliant languages
must provide a mechanism that allows access to named items that use a keyword of that
language as an identifier. C#, for example, uses the @ sign as an escape mechanism in this
case. However, it is still a good idea to avoid common keywords because it is much more
difficult to use a method with the escape sequence than one without it.
✓ DO use a generic CLR type name, rather than a language-specific name, in the rare cases
when an identifier has no semantic meaning beyond its type.
For example, a method converting to Int64 should be named ToInt64,
not ToLong (because Int64 is a CLR name for the C#-specific alias long). The following table
presents several base data types using the CLR type names (as well as the corresponding
type names for C#, Visual Basic, and C++).
Java vs. C#
You might have heard of the programming language called Java, since it has gotten a lot of
press in recent years, perhaps more than any language ever. Much of this attention is
unfortunately hype, but nevertheless, Java is a good programming language, and has many
pedagogical advantages over other languages.
44
C# Application Basics and Language fundamentals SKNSCOEK
Sun was the company that introduced Java, and understandably it wanted to control its
design and evolution. Unfortunately, Microsoft also wanted a piece of the action, and in
particular wanted to change Java in certain ways that suited its needs. This situation
became a legal nightmare, and eventually Microsoft decided that instead of trying to
influence Java, it would simply design its own language, which is called C# (pronounced "C
sharp"). This is the language that we will be using in CS-112. It is better than Java in
certain ways, but is so similar in most ways that once you have learned how to program in
C#, it will be trivial to transfer your knowledge to Java.
You may have also heard of other programming languages, such as BASIC, Visual Basic, C,
C++, Ada, Lisp, COBOL, FORTRAN, Haskell, ML, Python, Pearl, JavaScript (which is very
different from Java), and others. Although all of these languages are billed as "general
purpose," some are better at certain things than others, and thus one's application often
dictates one's choice of a language. For example, in the Computer Science Department at
Yale, FORTRAN is taught in CS-130 (for scientific computing), C in CS-323 (systems
programming), Lisp in CS-470 (artificial intelligence), Haskell and ML in CS-429 (functional
programming), etc. Java and C# are usually billed as being good at programming the World
Wide Web (WWW), i.e. the Internet.
But it so happens that Java and C# are good general-purpose programming languages
suitable for much more than just the Internet. They use many recent innovations in
programming language design, yet are also simple enough to use in a course such as CS-
112. Furthermore, once you know one programming language, it is much easier to learn
another. Java and C# have many attractive characteristics, including:
45