heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

118
C# programmin g Introduction By Per Laursen

Transcript of heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

Page 1: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

C#programming

Introduction

By Per Laursen

Page 2: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

1

IndholdThe Programming Process ...................................................................................................................3Environment ........................................................................................................................................5Statements ...........................................................................................................................................7Programming Fundamentals ...............................................................................................................9Types and Variables ..........................................................................................................................10Simple data output on the screen .......................................................................................................14Logic ..................................................................................................................................................16Pre-OO programming ........................................................................................................................18Object-oriented (OO) Programming .................................................................................................18The Class concept ..............................................................................................................................19Using objects of an existing class ......................................................................................................19Class definition elements ...................................................................................................................22Instance Fields and State ...................................................................................................................23Methods and Behavior .......................................................................................................................24Class constructors ..............................................................................................................................25Handling conditions ..........................................................................................................................28The if-statement .................................................................................................................................28Multi if/else-statements .....................................................................................................................32Switch-statements ..............................................................................................................................33Handling repetition ............................................................................................................................35The While-loop .................................................................................................................................35The While-loop .................................................................................................................................36The For-loop ......................................................................................................................................37Advantages of the for-loop: ...............................................................................................................38Arrays - Motivation ...........................................................................................................................39Arrays - Declaration ..........................................................................................................................39Arrays – Usage ..................................................................................................................................40The foreach-statement .......................................................................................................................41Lists ...................................................................................................................................................42Dictionary ..........................................................................................................................................43The concept of Inheritance ................................................................................................................45Base Classes and Derived Classes .....................................................................................................45The Object Class ...............................................................................................................................47Polymorphic variables and behavior .................................................................................................48

Page 3: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

2

Abstract methods and classes ............................................................................................................49Interfaces ...........................................................................................................................................50Defensive Programming ....................................................................................................................51Constants ...........................................................................................................................................56Static methods and classes ................................................................................................................57Enumerations .....................................................................................................................................59

Page 4: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

3

The Programming Process

If you have never tried something like programming before, it may seem like a mysterious activity – what is it really that we are doing? If we focus primarily on programming as a way of defining “business logic”, we are usually defining and manipulating a model of a small piece of the worldWhat does that mean more specifically? Suppose we wish to make a program for administration of a school. Then we probably need to store certain information about students (and other things) in the program. What things are relevant to know about a student? Date of birth? Shoe size? That will depend entirely on the requirements to the system, which the users of the system will have to define.The result will probably be that certain information is needed, while someinformation can be left out. So, the “model” of a student in the program may only contain certain information; the information which is relevant in relation to the requirements. Exatcly which pieces of information we include will depend on the specific situation, i.e. the specific requirements

Once we have figured out what information we need to include for each “concept” (student, teacher, classroom,...) in the model, we need to figure out how to represent that information in our program. We get to that part very soon!

In almost all cases, the information will need to be manipulated somehow. A very simple manipulation could be just to show the information to a user. A more complex manipulation could be to change the information. For a student, some information will probably never change (the date of birth), while some information will most likely change (the number of courses taken).

The way information changes can range from quite simple to very complex. The simplest change could simply be to change the current value to a new, given value. Say, when a student has taken one more course, the number of courses is increased by one. Other changes are more complex. If we e.g. store an average of the exams passed by the student, then passing an additional exam will require a recalculation of the average. In any case, there will always be rules for how to manipulate the information.

In programming, we then try to translate such rules (formulated in a human language) to instructions/logic written in a language the computer can understand, in this course the language C#. This will result in writing a number of statements.

Page 5: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

4

When we have large collections of statements, we can organize the statements into so-called methods, which we discuss later.

Page 6: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

5

Environment

What is C#• Object-Oriented Language• Part of Microsoft .NET Technology• Related to Java and C++

Most widespread tool for C# programming is Microsoft Visual Studio (newest version is 2013 update 3), abbreviated MSVS.

MSVS is a professional and commercial tool (Express version somewhat scaled down)Has quite a lot of facilities, huge knowledge base (+) Has quite a lot of facilities, not that easy to master (-)

We only need to use a fraction of the functionality Understand the structure of a “solution” or “project” Being able to navigate a projectUnderstand the role of the included files Add code to a projectCompile/build a project Run a projectUnderstand error messages from MSVS

Try not to be too intimidated by the environment (tunnel vision)

Top level of a C# application is a solution – an application i s a solution

A solution can contain one or more projects.

A solution consists of several files; we do not need to worry about all of the files

The Solution Explorer gives us an overview of the current solution. Do not worryabout what is contained in the sections Properties and References

Below these sections will be a list of files with the extension .cs. These files contain the actual source code of the solution

Page 7: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

6

In the Sandbox project, two such files Program.cs (generated by MSVS) InsertCodeHere.cs (made by me)

The files with the .cs extension contains C# classes – we get back to classes later

Classes contain methods, methods contains statements. A statement is one

singleinstruction for the program about what to do next (add two numbers, print something, etc.)

How do I open a Project/Solution in MSVS? Choose File | Open ProjectNavigate to the folder where the project is (note that a C# project is contained in a single folder in the file system)Click on the file with the same name as the project, with the extension .sln (.sln for “solution”)The project should now be loaded, and you can see it in the Solution

Explorer Try it for the Sandbox project

Before a program can be run (executed), it must be compiled and built. MSVS will Check that the code is valid (correct syntax)Compile the code into “native” .NET codeBuild the project, making it executable (black magic…)

Our main concern is to enter valid (and correct) code into a project. MSVS does the rest…

Note the difference between “valid” and “correct” code. A piece of code is “valid” if it obeys the syntax for C# code, which makes it possible to compile the code. However, we only consider a piece of code to be “correct” if it does what it is intended to do. That is an important difference!

Running a program: Press the little green triangle (or press F5)

Page 8: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

7

Statements

At the most fundamental level, all C# programs consist of a collection of C#statements.

Statements are organized into methods and classes; we get to that later

Statements are instructions to the program about what to do next – examples

are:Do some arithmetic or logical calculationRead or write data to e.g. a file, the screen, etc. Control the “flow of execution”Etc.

In the Sandbox project, there is essentially just one

statement. In the file InsertCodeHere.cs, we find:

// The FIRST line of code should be BELOW this lineConsole.WriteLine("Hello Class");// The LAST line of code should be ABOVE this line

The middle line is a statement!

The other two lines (green) are not statements; they are comments used for explanation

Only common property for all statements: they end with a “;” (semicolon)

Depending on their purpose, a statement has a certain syntax. The line in

theexample prints the text within the “ “ in a window on the screen

Syntax is very important, it MUST be obeyed 100 %. If not, you will get an error message from MSVS, if you try to run the program. In fact, If a statement is not syntactically correct, you will be notified e v en b e f ore ru n n i n g t he p r og r a m ! Wavy red lines will appear in the code.

Page 9: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

8

You will be annoyed by this… But there is no way around it!

Page 10: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

9

DO NOT ignore the red lines! They indicate that something is wrong, so fix it right away. Can be somewhat annoying that they appear as soon as you type in a statement

If an error appears – hover the mouse over the error indicator. A tooltip with an error description will appear. Alternatively press F6 (build solution) – a list of errors will appear.

Error descriptions can sometimes be more confusing than helpful – best advice is to read the code again, and use common sense

Good advice when programming:• Fix errors as soon as possible• Keep the number of “open” errors minimal• Test whenever possible

Page 11: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

10

Programming Fundamentals

What is programming? Presentation and Manipulation of data!

In Web-programming termsPresentation: Front-EndManipulation (Calculation): Back-End

Data manipulation can (a bit abstract) be broken down to: Receive the data needed for the calculationStore the data in memory, in suitable data structures Perform manipulation, according to business logic Store the result in suitable data structuresEnable the user to access the result

In back-end programming, we concentrate on: Data representation, using suitable data structures Data manipulation, using suitable methods

What types of data do we wish to manipulate• Numeric data• Text data• Logical data (true/false, Boolean logic)• (Binary data, e.g. pictures) – not the primary focus

Page 12: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

11

Types and Variables

How does a program store the data it needs to manipulate? Data is stored in the memory of the computer (RAM)

What is computer memory actually? Just a lot of elements (so-called bits), each of which can be either 0 or 1. We refer to a collection of eight bit as a byte. 256 possible distinct bytes.

Each byte in memory has an address. A modern computer has billions of bytes (one billion bytes = Gigabyte).

“Raw” storage of data – no matter the type – amounts to setting the value of certain bytes at certain addresses in memory. This is possible, but somewhat tedious.

Almost all programming languages therefore support the use of so-called

variables. What is a variable actually? It is a piece of memory; i.e. a certain amount

of bytes,located at a certain address in memory.

In order to make it easy – for humans – to use variables, we can give a variable a name, instead of having to refer to the actual address in memory. Also, we do not need to define the actual address of the variable ourselves – the program does that for us!

In addition to this, we must choose a type for the variable. This defines the kind of data the variable can store

Some types for storing data (“primitive types” – built-in):

int : Whole numbers (no decimals), from about -2,000,000,000 to 2,000,000,000.Uses 32 bits = 4 bytes

double: decimal numbers, with “high” precision. Why not exact values? Uses 64 bits= 8 bytes

bool: A true/false value. Usually uses 4 bytes, even though it in theory should

Page 13: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

12

use much less…

Page 14: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

13

string: A text of arbitrary length. Uses one byte for each character in the string.

The great advantage of having types is that we do not have to convert the data from the “human” type (e.g. a string) to the “computer” type, which is always 0/1 values.

Declaration of a variable in C#:

// Reserve space in memory for an int,// refer to the address by the name “age” int age;

// Put the value 24 in the bytes// referred to by “age” age = 24;

Note that the above types can also be written like Boolean (for bool), Int32 (for int), Double (for double) and String (for string). Choose the name that you prefer.

Arithmetic

A very important part of most programming tasks is arithmetic. Almost all programming languages support arithmetic, since much data manipulation has an arithmetic nature – we perform calculations. The specific syntax may vary somewhat

C# supports most common arithmetic operations, but there are certain operations that differ from “classic” arithmetic.

We have already seen assignment:

int age;age = 24; // Assignment, NOT an expression

Very important to note that this means, “set age equal to 24”. It does NOT mean “age is equal to 24” (which may be true or false).

Simple arithmetic:

int age;age = 24 + 32; // Now age is 56

Page 15: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

14

age = age + 10; // Now age is 66

int legalAge = 18;age = legalAge + 10; // Now age is 28

The right-hand side is always evaluated first, and the result can e.g. be stored in a variable. The same variable can occur on both sides of the “=” (assignment) sign.

Note that the exact type is important. Consider this assignment:

int a = 7; int b = 4;int c = a/b; // a divided by b

The result is NOT 1.75 as you might expect, but 1. When doing arithmetic with integers, the result will also be an integer. Note also that there is no rounding of the result. It might seem more natural that c should become 2, but it doesn’t!

There are some non-standard operators in C#, for instance the “remainder” operator % (or “modulo”)

int a = 7 % 4;

The result of the above is 3 – the remainder when dividing 7 with 4 (integer division)

Usual rules for precedence apply, so e.g.

int a = 2*3+4; // This is 10, NOT 14

Some forms of conversion between types are possible, like:

int a = 7;double b = a; // b is now 7.00000… double c = b / 4; // c is now 1.75

Type conversion is a larger subject – short story: you can convert automatically when you do not lose information (7 -> 7.0 OK, 7.4 -> 7 not OK)

Page 16: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

15

Use of brackets is also allowed, and follows standard rules. Good idea to use brackets to increase readability, even if they are not strictly necessary.

Page 17: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

16

Simple data output on the screen

Even though Back-End programming is not about GUI, we still need – as part of learning about programming – to output data to the screen, so we can see if our program works as expected. We have actually seen this already:

Console.WriteLine("Hello Class");

So, the statement Console.WriteLine will output something on the screen. In the above example, it will output:

Hello Class

In general, Console.WriteLine will output the data we specify in the brackets () following the Console.WriteLine words themselves. If we write some within quotation marks, like “Hello Class”, then this is interpreted as data of the type string, and the string (minus the quotation marks themselves) is printed.However, Console.WriteLine is rather flexible. Consider the below piece of code:

int age = 21;Console.WriteLine(age);

If you execute this piece of code, the program will print:

21

Why did it not print the word “age” instead? In general, Console.WriteLine will print a string. If we put something else in the bracket, the program will try to convert it to a string. That is, not the variable itself, but the v al u e of the variable. In fact, all values can be converted to a string! What was actually printed in the example is the string “21”, because the value 21 was converted to the string “21”. This can be done for all types of values.

Also very useful is the ability to “chain together” values, for instance like:

int age = 21;Console.WriteLine("The age is " + age);

Page 18: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

17

If you execute this piece of code, the program will print:

The age is 21

What is going on inside the brackets? Actually several things. First, it seems we are adding two things – a string and an int. Can we even do that? In general, you can only add things of the same type. But since any value can be converted into a string, the value of age (21) can be converted into a string. So, we are then trying to add “The age is “ and “21”. Since addition of two string is defined as concatenating the string (writing the first string after the other), the result of the addition is “The age is 21”, which is then printed to the screen. This ability if chaining together several values (you can add as many values as you like inside the brackets) is very useful for outputting a message on the screen.

Using string concatenation is one way of printing a longer message – consisting of a mix of text parts and variable values – on the screen, using Console.WriteLine. However, there is another way to do this which might be more convenient, by using a so-called formatting string.

Suppose we have two variables like:

String name= “James”;int age = 23;

and want to print a message like:

James is 23 years old

Using a formatting string, this will look like:

Console.WriteLine("{0} is {1} years old", name, age);

Notice the use of the curly braces, like the {0} and {1}, inside the string. This should be understood as: Take the value from the first variable following the string (in this case, the variable called name), and replace {0} with that value. Then take the value from the next variable (age), and replace {1} with that value. So in this example, {0} is replaced with “James”, and {1} is replaced with “23”, producing the string above. Note that you can use this principle for as many variables as you wish, by adding {2}, {3} etc. to the formatting string, and adding the variables themselves after the formatting string (separated by comma).

Page 19: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

18

Logic

The ability to work with Bo o l ean l og i c is also a very important feature of C#.

Boolean logic: expressions can evaluate to true or false, Becomes very important for controlling the flow of execution through control statements (later).

The most common use of boolean logic is when testing for e q u a l ity or testing for a r e l at i o n (strictly speaking, equality is also a type of relation…)

Testing for equality: Are two entities (e.g. numbers) equal to each other, or different from each other

Testing for relation: Do two entities (e.g. numbers) have a particular relation to each other, like e.g. the first being greater than the other

Just like for arithmetic, there are a number of relational (or logic) operators available in C#

== means “equal to” (notice two equal-signs!!)!= means “not equal to”> means “greater than”< means “smaller than”>= means “greater than or equal to”<= means “smaller than or equal to”

Notice that we use these operators to co mp a r e values, NOT to change values!

Any expression using these relational operators will evaluate to either True or False, which are exactly the values a variable of type bool can have.

int a = 7;bool b = (a == 7); // b will be Truebool c = (a < 7); // c will be False bool d = (a <= 7); // d will be True

Page 20: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

19

Fairly straightforward for integers, slightly more tricky for double (decimal numbers).4.0000000002 is NOT equal to 4.0000000001 (but maybe it is “close enough”?)

Comparing strings is also done using the “==” operator

How can we test, if the value of a variable is inside an interval, e.g. between 10 and 20 (included)?

int a = 14;bool lowLimitOK = (a >= 10); bool highLimitOK = (a <= 20);bool isInInterval = lowLimitOK && highLimitOK;

Notice the operator “&&” – this means “and”.The expression A && B is only true if A is true and b is true as well.

We also have an “||” operator – this means “or”The expression A || B is true if A is true o r b is true. Note that the expression is also true if both A and B are true

Finally, we have the “!” operator – this means “not”The expression !A is true if A is false, and vice versa. The ! operator can be said to “reverse” the value of an expression.

“or” is obviously more forgiving than “and” . By using the operators, we can combine expressions to form quite complicated expressions

bool isOK = ((a < 20) && (a > 10)) || (a > 60);

Logical expressions become harder and harder to understand as they grow in length, beware…

Another way to look at the values these operators produce is to use a so-calledtruth table:

A B A && B A || B !ATrue True True True False

Page 21: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

20

True False False True FalseFalse True False True TrueFalse False False False True

The concept of functions

With arithmetic and boolean expressions, we can begin to write non-trivial pieces of business logic. For instance, we can calculate the average of three integers:

int average = (a1 + a2 + a3) / 3;

This is rather simple, but if we must do this many places in our code, it can become tedious to write again and again. This is even more problematic if the logic is more complex. Instead of this, we would like to define the logic in one place, and then refer to that logic instead of writing it again over and over. We can do this by defining a so-called function.

A function is a fundamental concept in programming. The syntax may vary from language to language, but you always need to

1. Name the piece of logic, so you can refer to it2. Define what input the function needs3. Define the logic of the function4. Define what the output of the function is

A function for calculating average as per above could in C# look something like this (details of syntax not so important yet):

int CalculateAverage(int val1, int val2, int val3){

int average = (val1 + val2 + val3) / 3; return average;

}

This function is called CalculateAverage, takes three integer as input, and produces one integer value as output.We can now refer to this logic when we wish to calculate an average. For the previous example, it will look like:

int average = CalculateAverage(a1, a2, a3);

Page 22: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

21

We say that we call or invoke the function CalculateAverage. Now the caller of the function does not need to know the details of the logic, only how to refer to it!When we call the function, we can use the output – which is more precisely called the return value – in the same way as any other value, for instance in an assignment statement as above. We can even use function calls in expressions, like

int total = func1(x) + func2(y);

assuming that the functions func1 and func2 were defined.

You can compare a function in C# with a function in mathematics: It takes some input, and produces some output, depending on the specific nature of the function. In programming, a function can however take many values (even zero) as input.

Pre-OO programming

We have now been introduced to types and variables, plus basic arithmetic and logic statements.

In the “old days” of computer programming (before 1990) – before so-called Object- Oriented programming – this was more or less the level of abstraction programs were written at.

Goo d : Using variables and types allows us not to worry about details of data representation and memory management.

Ba d : Still quite far between real-life concepts such as Student, Employee, Animal,… and data representation.

Note that it is quite possible to make very complex software using this “old school” style. Still, it was recognised that a different “paradigm” would make it possible to create better representations of real-life concepts in software.

Page 23: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

22

Object-oriented (OO) Programming

In non-OO programming, data and procedures are separatedNo encapsulation, data belonging to the same conceptual entity is spread out over multiple data structures.

In OO, data and procedures are joined into objects. The state (data) and behavior (methods) of objects of a certain type are specified in a class definition.

Advantages:

1. Code structure will be more similar to conceptual models.2. Encapsulation – the user of a certain class only gets to know what the user

needs to know. There is freedom to change the internal structure of a class.3. Reuse – OO contains facilities that allows reuse of code through e.g.

inheritance.

NOTE: OO is still “just” a tool for helping human beings in developing computer programs – internal representation in memory is the same as before.

The Class concept

A class definition is a “recipe” or “blueprint” that defines how an object of this particular class will behave.

It defines the objects “interface” to the outside world, by defining methods that a user of the object can invoke on the object.

Methods are collections of statements, such that a sequence of statements can easily be executed by “calling” the method. By “calling” we mean that somebody invokes the method, thereby executing the statements in the method.

It defines the internal structure of the object, more specifically the state of the object, which is represented by one or more instance fields (a special kind of variables).

It may also define some internal methods, that can help the object perform its tasks, without being directly available to an external user of the object.

Page 24: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

23

The interface to the external user should preferably not change. If it changes, the user of the object may have to change his code, and we wish to avoid that. As long as the interface does not change, we have freedom to change the internal structure, without affecting an external user.

Using objects of an existing class

It is possible to start using classes without actually knowing anything about how to define classes.

Page 25: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

24

We use a class by creating an object of that class. That is, an object which will behave as specified in the class definition.

// Create a new Student object Student s1 = new Student();

Note that this is actually quite similar to a statement like:

int age = 19;

On the left-hand side, we have the declaration of a variable, consisting of a t yp e and a n a m e of the variable.

On the right-hand side, we have an actual value which we assign to the variable. In the new case, that value is actually a n e w o b ject of the type Student.

The keyword new is always used when creating a new object, followed by the name of the relevant class (here Student).

Now the variable s1 refers (points to) to an object of type Student, and we can begin to call methods on the object.

When a variable refers to an object of a certain type, we can call methods on that object by using the so-called “dot” syntax:

// Call a public method s1.PrintName();

Notice the dot (full stop) that follows the variable name. After the dot, we write the n a m e of the method we wish to use.

How can we know what methods that are available? If we have written the method ourselves; look in the code . In a more professional system, there will be some documentation of the available methods, that you can refer to.

In Visual Studio, you will see that a list box of available methods pops up, as soon as you type the dot. Don’t be confused!

In general, in order to call a method on an object, we must suppy

Page 26: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

25

The method nameAny parameters needed (the parameter list)

Some method may require information from the caller in order to do its job. We could imagine a method on a Student object:

s1.SetTestResult(“English”, 80);

This method requires the caller to provide two parameters: A string (the name of the subject which was tested for), and an int (the result of the test). Parameters are always provided inside the brackets () that follows the method name, must be provided in the correct order, and must have the correct type.

Other methods may return information to the caller. This is called a return value. This will be indicated in the documentation. The special return value void means “no return value”. It may seem strange that you have to specify that a method does not return any information – couldn’t we just not write anything? The syntax of C# is so that you mus t specifiy what a method will return to the caller, so the word void has this special meaning of indicating that nothing comes back when calling this method.

If we want to use the return value for something (we usually do), we need to “pick it up” in a variable:

int average = s1.GetAverageTestScore();

Now the variable average will have the value which was returned by the method call.

Note that when a method call returns a value, that value can be used directly just as a simple variable, e.g. like:

Console.WriteLine(s1.GetAverageTestScore());

We can n o t , however, make assignment in this way:

// NOTE: This will NOT work!

Page 27: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

26

s1.GetAverageTestScore() = 75;

Value types and Reference types

A variable that has a so-called primitive type like int will be a value-type variable. What does that mean? It is sort of a technical detail; it means that if you create a variable like:

int age1 = 18;

then the program will allocate a bit of memory in the computer, and place the actual value of the variable there. If you create another variable like:

int age2 = age1;

then another piece of memory is allocated, even though we are using the same value. In other words; these variables will occupy two different places in memory, and we can change their values independently.

However, objects work in a different way. The stamement

Student s1 = new Student();

will create a new Student object somewhere in memory, and then set s1 to be a reference to the object:

The area in memory called s1 does not contain the data from the Student object itself, but rather an address to where this data is stored. This more indirect way of storing data is called “by reference”, and s1 is thus a reference type variable.

18Age1 18Age2

S1 (Student object)

Page 28: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

27

This is not really something you need to think much about, but it does have some consequences you might not expect. Observe the two lines of code below, which are similar to the example before with age1 and age2:

Student s1 = new Student();Student s2 = s1;

How many Student objects have been created? Only one! But we now have two variables of reference type which both refer to the same Student object, like so:

Any action we perform through the s1 variable – like changing the value of an instance field – will thus be “visible” through the s2 variable, since both variables are referring to the same object:

s1.SetZipCode(2765);int zipCode = s2.GetZipCode(); // Returns 2765

It is also possible to let a variable of reference type refer to “nothing”. This can be useful if we have a reference type variable which should not refer to any object initially. This is called a null reference, like so:

Student s1 = null; // null means “nothing”

Note that you can always set a reference type variable to null; it does not need to be the initial value.

Having null values is useful, BUT note that it does not make sense to call any methods on a reference type variable which is set to null. Trying to do so will make the program respond with an error message, and halt the program!

Student s1 = null;string name = s1.GetName(); // NO!!

The actual error will be a so-called “null pointer exception”, which is a very common error in programming… And if you think about it, it is of course a sensible reaction

S1 (Student object) S2

Page 29: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

28

from the program. What name should this piece of code return, now that the variable s1 does not refer to any object…?

Class definition elements

A definition of a class is placed in a separate file, which has the extension .cs. The class definition itself must contain:

The “signature” of the class definition. The first line will contain the name of the class; the rest of the definition (the body) must follow inside the area delimited by { and }

public class Student{// Rest of class definition is here…

}

Zero or more instance fields. An instance field is a variable, which belong specifically to an individual object. Each object of a given class will have its own “set” of instance fields. Setting the values of the instance fields on one object will not affect the values of the instance fields in another object.

One or more “public” methods. The public methods are the methods that a user of the class can invoke on the object. These mehtods fall in two categories: Those that “ask a question” to the object (accessor), and those that may change the state of the object (mutators). Note that a method definition is also delimited by { and }. The collection of statements inside the delimiters is called the b o d y of the method.

Zero or more “private” methods. The private methods are helper methods, that help the public methods complete their tasks. They are n ot available to an external user.

One or more “constructors”. A constructor is a special kind of method, that is invoked when the object is created. Its primary purpose is to ensure that the object is created in a well-defined state, i.e. give the instance variables well-defined values.

Page 30: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

29

Instance Fields and State

Class definition (part of…)

public class Student{private string name; private int yearOfBirth; private int testsTaken; private bool isMale;

}

The four lines between the { and the } define four instance fields, that are not directly available for a user; this is indicated by the private keyword in front of each definition. In Object-Oriented programming, an instance field is typically made private, since an external user should n ot manipulate the values of the instance fields directly, but rather do it indirectly by calling methods.

All of the values for the instance fields define the state of a specific object. Recall that state is indeed object-specific. Two different objects of the same class will have the same set of instance fields, but the v al u es of the instance fields may be different:

State of one object: { “John”, 1988, 3 , True}

State of a different object: { “Susan”, 1984, 0, False}

Page 31: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

30

Methods and Behavior

Class definition (part of…)

public class Student{public void PrintName(){

Console.WriteLine(Name);}

public void IncreaseTestsTaken(int NewTests){

TestsTaken = TestsTaken + NewTests;}

public int GetTestsTaken(){

return TestsTaken;}

public bool IsStudentMale(){

return isMale;}

}

A method definition consists of access specifierreturn typemethod name parameters

Some methods return information about the state of the object. This could simply be the value of an instance field, or it could be a compound or calculated value.

Note that when a method does not return any value, we indicate this by using the

Page 32: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

31

void return value.

Page 33: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

32

Methods that return information are often called accessors, while methods that change the state are called mutators.

Some methods are neither accessors or mutators, but have some kind of “side effect”, like printing something (not very common in back-end). Also, some methods may both be an accessor and a mutator. Usually not recommended, since it may indicate too many responsibilities for the mehod.

Note that we use the keyword public to indicate that a method is available to an external user. Only methods that an external user is intended use should be marked public. A private method can only be used by other methods in the class itself.

Instance fields are usually private. We want to encapsulate the true representation. Users do not need to know that representation, and we then can change it without affecting the user.

Note that we can use local variables inside a method. They are used to make caluclations easier, and are only “alive” while the method executes. They can n ot be accessed by other methods in the class, or by external users.

Class constructors

A constructor is invoked when we create a new instance of a class, i.e. when we create an object:

// We call a constructor without parameters Student s1 = new Student();

The primary purpose of the constructor is to set the state of the object to something sensible and well-defined.

In many cases, it will not make sense to create an object without having certain information available, like name and birth for a Student. We would then use a constructor with parameters:

// We call a constructor with parameters Student s1 = new Student(“Per”, 1967, True);

Page 34: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

33

W e define constructors! And we may define as many as we want; one without parameters, and one (or more) with parameters. Note that if we do not define any constructors at all, there will still exist a “default” constructor with zero parameters, that does nothing. This is usually not a recommended approach.

In general, if it does not make sense to create an object without certain information, the constructor should include parameters that represent this information. This prevents that objects can be created without this information.

Example of a constructor for the Student class:

public class Student{

public Student(string s_name, int s_yearOfBirth, bool s_isMale)

{name = s_name; yearOfBirth = s_yearOfBirth; isMale = s_isMale; testsTaken = 0;

}

...// Methods will follow here

}

Note two very important features for a constructor:It looks like a method, but it always has the same name as the class itself It has no return typeYou can always recognize a constructor by these features.

The statements inside the constructor do exactly what we stated before: set the values of the instance fields to well-defined values. Some of these values are given from the outside, in this case name, year of birth, and the gender indicator (is male or not), while the number of tests taken is set to 0. The first three values will thus be “individual” for each new object, while the last one will a l w a y s be set to 0 for all new Student objects. This is very typical; some initial values are individual and

Page 35: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

34

require information from the caller, while other values have a sensible initial value which is the same for all objects of that class.Note also the names of the parameters in the constructor (s_ and then something). Why did we not just write the constructor like:

public Student(string name, int yearOfBirth, bool isMale)

{name = name; yearOfBirth = yearOfBirth; isMale = isMale; testsTaken = 0;

}

If we did this (it is actually legal syntax), then we suddenly have two things with the same name; the instance field name and the parameter name. The program cannot figure out that the left-hand side should be the instance field, while the right-hand side should be the parameter. In this case, it will use the parameter on both sides, which is not what we want.

In order to solve this, we can do two things. We can use different names as in the s_ example, or we can use the keyword this. That is very commonly used, and looks like:

public Student(string name, int yearOfBirth, bool isMale)

{this.name = name; this.yearOfBirth = yearOfBirth; this.isMale = isMale; this.testsTaken = 0;

}

The keyword this should be understood as “this specific object”, so writing this-dot- something will refer to elements inside this specific object, in this case the instance fields. It is just a matter of taste if you prefer to use the “different names for instance fields and parameters” approach, or the “using the this keyword”

Page 36: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

35

approach. The latter approach is however very common used in real life, so you should know about it.

Get/Set-methods and properties

Instance fields are – as mentioned above – usually private, so we need methods for accessing and changing their value. For a game, we might have an instance field called highScore:

private int highScore;

with two simple methods like:

public int GetHighScore(){ return highScore;}

public void SetHighScore(int newHighScore){ highScore = newHighScore;}

These are two archetypical methods for retrieving and setting the value of an instance field:

The Get-method, with these characteristics:Returns the current value of an instance fieldNamed GetX, where X is the name of the instance field, like GetHighScoreIs an accessor method

The Set-method, with these characteristics:Changes the value of an instance field to a provided valueNamed SetX, where X is the name of the instance field, like SetHighScoreIs a mutator method

Methods like these are present in almost all class definitions, and many programming tools can even auto-generate code for such Get- and Set-methods.

Page 37: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

36

The methods need not be as trivial as in the example. You could imagine that for a Set-method, we would like to validate the provided value. For the SetHighScore method, we could e.g. check if the provided value is actually higher than the current high score, and only change the value of highScore if that is the case.

Using code like this from another part of the program will then look like (assuming we have defined a class called Game with some appropriate methods):

Game theGame = new Game();... // The game is played a few times

int currentHighScore = theGame.GetHighScore();... // Do something with the value

int newHighScore = theGame.GetMostRecentScore();theGame.SetHighScore(newHighScore);

Methods like these have always been part of object-oriented programming. With the introduction of C# in 2000 came a new way of manipulating instance fields called properties.

A property is essentially a set of two methods, which can be used with a syntax very similar to how you would access a public instance field. This initially sounds somewhat confusing… Rewriting our example from before as a property would look like:

private int highScore;

public int HighScore // This is the property{ get { return highScore; } set { highScore = value; }

Page 38: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

37

}

Effectively, we have just wrapped the code from the previous Get- and Set-methods into the get- and set-part of the property. However, using this code from another part of the program will now look like:

int currentHighScore = theGame.HighScore;... // Do something with the value

int newHighScore = theGame.GetMostRecentScore();theGame.HighScore = newHighScore;

At first, this may look like we are now using the instance field highScore directly…but we are not! Notice we write HighScore with a capital H. This means we are using the property, not the instance field itself!

It may be confusing to figure out when the code in the property is executed. When we use the property on the left-hand side of the assignment operator (the equal-sign “=”), like this:

theGame.HighScore = newHighScore;

it will be the set-part of the property which is executed, with value taking on the actual value of newHighScore. Likewise, when we use the property on the right-hand side, like this:

int currentHighScore = theGame.HighScore;

it will be the get-part which is executed. So, even though the code syntactically looks like we are not calling any methods, we are indeed calling the get- and set-methods in the property. Just as with the traditional Get- and Set-methods, we can put as much code into the property methods as we need.

So what is best: traditional Get- and Set-methods or properties? Mostly a matter of taste and habit… Syntax for properties is more compact, but maybe more confusing to beginners. We will stick to traditional Get- and Set-methods here.

Page 39: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

38

Handling conditions

So far, we can only define “deterministic” sequences of statements, that will always be executed in the same order. This sets significant constraints on the complexity of code we can write.

To create more complex code, we also need statements that control the “flow” of other statements; that is, the order in which other statements are executed.

These statements are called “control statements” – main types of control statements are:Conditional statements Repetition statements

In the category of conditional statements, the if-statement is the most prominent member

Other conditional statements:if/else-statement Switch-statement

The if-statement

The business logic we are trying to implement will very often contain conditions.

E x a mpl e s :

Only allow withdrawal from a bank account i f the balance if larger than the amount to withdrawA car is defined as being a family car i f it has at least four seats a n d has air conditioning

The C# syntax for a conditional statement is:

Page 40: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

39

if (condition){// sequence of statements

}

Three elements in an if-statement: The keyword ifThe logical condition (which is a boolean expression) inside the brackets The code block inside the { and }

Remember that a boolean (or logical) expression will always evaluate to true or false. The expression can be simple or very complex, but it must always evaluate to either true or false

How will the withdraw method from the BankAccount class look, if we add the condition that the balance must be larger than or equal to the amount we are trying to withdraw?

if (balance >= amount){

balance = balance – amount;}

It is very important to understand the main properties of the if-statementIf the condition evaluates to true, the code inside the code block will be executed o n c e , and the program will then continue with the statements following the if- statementIf the condition evaluates to false, the code inside the code block will be skipped(i.e. n ot executed), and the program will immediately continue with the statements following the if-statement

If the code block only consists of one line, it is possible to write the code like this:

if (balance >= amount) balance = balance – amount;

For readability, it is however recommended always to use the { and } to delimit the code block

Page 41: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

40

WATCH OUT: Do n ot put a semicolon right after the condition. This is an error, but not a syntax error! The if-statement will then “do nothing” no matter the value of the condition.

The if/else-statement

In many situations, there will also be a natural alternative action if the condition evaluates to false.

We could write this as:

if (balance >= amount){balance = balance – amount;

}if (balance < amount){Console.Writeline(“ERROR!!”);

}

This is possible, but somewhat dangerous. Can we be absolutely sure that the two conditions are mutually exclusive, and that one will always be executed?

It is more convenient (and safe) to include the alternative as an integrated part of the if-statement itself – this is done by adding an else-part to the statement:

if (balance >= amount){balance = balance – amount;

}else{Console.Writeline(“ERROR!!”);

}

This is a safer approach; we are guaranteed that ex a ct l y one of the statements is always executed. Never zero, never both!

Page 42: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

41

Nested if-statement

It is also possible to “nest” if-statements within each other. We could e.g. have a condition like:

if ((age >= 18) && (nationality == “Danish”)){Console.Writeline(“You can vote!”);

}

This is perfectly legal, but could also be written as:

if (age >= 18){if (nationality == “Danish”){

Console.Writeline(“You can vote!”);}

}

Notice the indentation – it makes the code easier to read!

In general, the code block can contain any code you want, for instance additional conditional statements, like above. Watch out for very complex combinations, though…

You can, of course, also nest if/else-statements

Page 43: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

42

Multi if/else-statements

Often you will have more than two possible alternatives. For instances translation of scores to grades:

If score is above 90, grade is A If score is above 75, grade is B If score is above 55, grade is C If none of the above, grade is D

This can be written as a nested if/else-

statement: if (score > 90){

grade = “A”;}else{

if (score > 75){grade = “B”;

}else{if (score > 55){grade = “C”;

}else{grade = “D”;

}}

}An alternative way of writing this is:

if (score > 90){

Page 44: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

43

grade = “A”;}else if (score > 70){grade = “B”;

}else if (score > 55){grade = “C”;

}else{grade = “D”;

}

They are logically equivalent, but the latter can be easier to read. Mostly a matter of style and preferences.

Switch-statements

Sometimes the business logic has a nature where there is a distinct outcome for each possible specific value of a variable.

Maybe the logic for calculating child support could be like this:

Number of children Child support (kr. per month)0 01 12002 20003 2600>3 3000

There is no simple formula for this dependency, so we could write it as a nested or multi if/else-statement. However, the switch-statement allows us to “directly” choose an alternative based on a specific value:

switch (noOfChildren)

Page 45: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

44

{case 0:

childSupport = 0; break;

case 1:childSupport = 1200; break;

case 2:childSupport = 2000; break;

case 3:childSupport = 2600; break;

default:childSupport = 3000; break;

}

There are several important properties to note about the switch-statement:1. At the outermost level, we use the keyword switch, followed by the

expression (typically just a variable) that we “switch on” in brackets ().2. We write a case statement for each of the cases that we wish to handle

individually, using the keyword case followed by the actual value, followed by “:” (colon, n ot semicolon!)

3. Each case contains a sequence of statements, concluded by a break statement. The break statement indicates that no more of the code within the case statement should be executed. It is perfectly legal to include if-statements, etc. in the code before the break statement, but often you will put just a single line of code.

4. If the value is not handled explicitly by a matching case statement, it is caught in the

5. default statement, and the lines of code specified here are executed

Again, there is nothing you can do in a switch-statement that you cannot do in a if- statement; they are logically equivalent.

Choose the type of statement that you feel fits the problem best, and makes the code easier to understand.

Page 46: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

45

Handling repetition

The if-statement allows some control of execution flow, but we still cannot easily repeat a block of statements

In practice, we very often need to r e p e a t a block of code multiple times, while some condition is true. For that purpose we have loop statements, aka repetition statements

Common features: the condition!

Types of repetition statementsWhile-statement For-statement Foreach-statement

The foreach-statement is closely related to so-called co lle ct i o n s , so we only look atwhile- and for-statement for now.

The While-loop

The basic structure of the while-loop:

while (condition){// Code block

}

The code block can contain any C# code, including other control statements (code nesting)

The condition is the same type as we saw for if-statements; a logical condition, that evaluates to true or false.

Page 47: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

46

If the condition is true, the statements in the code block are executed once. This is called an iteration.

After an iteration, the condition is checked again. If it is still true, another iteration is performed. If it is false, the code block is skipped, and the statements after the while-statement are executed.

How can the value of the condition change? The value of the condition is evaluated after each execution of the code block, so some of the statements in the code block must affect the value of the condition.

If no action in the code body can affect the condition, we have an infinite loop

The While-loop

Typical variants of while-loops: Counter-

controlled while-loop:

int counter = 1; while (counter < 10){

// Do something... counter = counter + 1;

}

Appropriate when we wish to repeat the code a fixed (either at compile-time or at run-time) number of times

Sentinel-controlled while-loop:

int grade = getGradeFromUser();while (grade >= 0){

// Do something...grade = getGradeFromUser();

}

Page 48: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

47

Appropriate when some external source (e.g. the user) controls how many times we need to execute the code. Execution stops when the user inputs a certain flag value.

NB: A flag value must n ot also be a valid data value!

Note that four properties are common for both types of loops

I ni t i a l i s atio n : Before the loop itself is entered, we usually – but not always – initialise some variable that is also used as part of the condition

C on di t i on : The logical condition itself, which is evaluated before performing another iteration of the loop

Ch a n ge : Since the condition itself is fixed, at least one of the values of the variables in the condition must have the chance to change during an iteration. Otherwise, we have an infinite loop. Formally put, the probability that something changes must be larger than 0 (zero).

C o d e b l o c k : The sets of statements that are executed during an iteration. Some of those statements must cause the change mentioned above.

The For-loop

As mentioned above, a counter-controlled while-loop has four components:

int counter = 1; // Initialisation while (counter < 10) // Condition{

// Do something... // Code block counter = counter + 1; // Change

}

This construction is so commonly used, that another repetition statement – the for- loop – is available for this purpose. This is the generic structure of the for-loop:

for (initialisation; condition; change){

Page 49: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

48

// Code block}

Page 50: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

49

A very typical for-loop:

for (int counter = 1; counter <= 10; counter++){// Code block

}

Note that counter++ means “increase the value of the variable counter by one”

Advantages of the for-loop:

Statement “header” takes care of “all” Harder to forget e.g. the change statement

Except for some very special cases, for-loops and while-loops are equivalent – you can write any repetition statement as either a for-loop or a while-loop.

However, using for-loops in the case of counter controlled repetitions is the common recommendation.

Legal, but not advisable:

for ( int grade = getGradeFromUser(); grade >= 0;grade = getGradeFromUser())

{// Do something...

}

In general:Use for-loops for counter-controlled repetitionsUse while-loops for sentinel-controlled repetitions

Page 51: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

50

Page 52: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

51

Debugging a program

Once your programs reach a certain complexity, they may not work correctly the first time you run them. There may thus be errors (or bugs, as they are often called) in our code. How do we find and correct such bugs? This process is called debugging.

A first – and quite obvious – technique is simply to read the code closely. In many cases, the bug is quite simple (like using a minus instead of a plus somewhere), and surprisingly many bugs can be caught this way. Even better is to try to explain the code to someone else; the process of stating the intention of the code aloud will often reveal bugs.

If such manual techniques are not successful, you can add some statements to the program that print out useful information to the screen, e.g. inside a loop. It could be the value of a variable that seems to cause the problem, like:

// Trying some divisionsint divideBy = 0;while (divideBy < 10){ // The below line is for debugging Console.WriteLine("Dividing by:{0}",divideBy);

int result = 100 / divideBy; Console.WriteLine("Result is {0}", result); divideBy++;}

Adding such printing statements to a program can quickly become a bit of a mess, and it is tedious to remove again. A slightly better technique is to use the built-in statement Debug.WriteLine instead; this prints to the Output window in Visual Studio instead, and only prints when in Debug mode. Still, adding and managing these printing messages is a somewhat old-fashioned approach to debugging.

A more powerful and elegant technique is to use the so-called integrated debugger, which is part of Visual Studio. Almost all modern programming tools contain an integrated debugger.

Page 53: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

52

The integrated debugger can help with debugging in a lot of ways, and getting familiar with the debugger is definitely a worthwhile investment if you are serious about programming. Still, you can get quite far with knowing just a few things.

A very useful concept is a breakpoint. A breakpoint is a position in the code (a specific statement) that you choose. When you then run the program, the program will halt (not terminate!) at the breakpoint. In a sense, the program is paused. You choose the location of a breakpoint simply by clicking in the leftmost part of the code editing window (a red dot will appear):

You remove the breakpoint by clicking on it again.With the breakpoint in place, you can now run the program. Once the program execution reaches the breakpoint, the program halts. What now? Now you can inspect the current values of all variables simply by hovering the mouse over the variable in the code editor window. This is in itself quite useful, since you often see that the values might be different from what you expected. If you then want the program to continue the execution from the breakpoint, you simply click the green triangle, just as when starting the program (note that the text at the button now says “Continue”). Note that you can place multiple breakpoints in the program; hitting Continue will then resume program execution until the next breakpoint is reached.

The above features – being able to halt the program at a breakpoint and inspect variable values by hovering over them – are by themselves extremely useful for debugging. Getting used to using this feature will save a lot of time. The next feature to know is the ability to “step” through the program. When you reach a breakpoint, a small set of buttons appear (they can also be found under the “Debug” menu):

These three buttons are called:Step into

Page 54: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

53

Step overStep out

These “step” buttons enable you to advance the program execution by a single statement at a time, just as if all lines were actually breakpoints. But if execution has reached a certain statement, what is then the next statement to be executed?

The obvious answer would be the next line of code in the method where we placed the breakpoint. If you click the “Step over” button, the arrow marking the current position in the program will indeed advance to that statement (note that this need not be the physically next line, since we might have conditional statements, loops etc. in play here).

But what if the statement we are currently at is a method call? If we want to investigate what happens inside that method call, we can use the “Step into” button. This will take us into the code called by the method call. In this way, you can step infinitely deep into methods being called by other methods (cue music from Inception... ).

If you step through all statements in the called method, you will eventually be returned to the calling method – if you want to be taken immediately back to the calling method, you can click on “Step out”, which then finishes the method call. Using these three ways of stepping through the code is also extremely useful.

In total: as soon as your programs grow beyond trivial, it is a really good investment to familiarise yourself with the most fundamental features of the integrated debugger. The best way to learn this is – as always – to practice!

Page 55: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

54

Arrays - Motivation

We will very often need to represent multiple entities of the same type, say collections ofInteger measurement results Student objectsNames as text strings

Using a single variable for each instance quickly becomes quite unmanageable. Imagine having to represent 100 students in your program, and having variables like:

Student s1 = …; Student s2 = …; Student s3 = …;… // and so on, and so on… Student s100 = …;

An array object can store many instances of identical type, and still allows manipulation of individual elements. This is a much more flexible solution.

Arrays - Declaration

Since an array is indeed an object, it is Created with a new statement Referred to by a variable (by reference)

The variable is declared as follows:

int[] numberArray; // Declares a variable

The creation of the array itself looks like:

// Array with 10 elements numberArray = new int[10];

It is important to notice the use of []. Also note that the actual size of the array is specified in the creation, n ot the declaration.

Page 56: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

55

An array has a fixed size, but it can be changed by using the resize method, defined in the Array class:

// Resize array to 20 elements Array.resize(ref numberArray, 20);

Resizing is somewhat expensive, so we should avoid it. There are other and much better ways to deal with the situation where the number of elements is not know in advance, and we will discuss them later.

Arrays – Usage

Once the array contains elements (see later), we can use each element just as it was an ordinary variable.

Each specific element is specified by its po si t i on in the array; we usually call this theindex.

// Add 2 to the fifth element in the array numberArray[4] = numberArray[4] + 2;

Catch! The first element in the array has index 0 (zero). In an array of 10 elements, the last element has index 9!

Notice that we can use array elements both on the left-hand side and the right-hand side in an expression; they act just as any other variable of that type.

We can initialise an array directly in the code, if the values for all elements are fixed:

// Initialises the array to five elements int[] numberArray = {12, 42, -9, 34, 10};

We will very often use arrays together with some type of repetition statement

int[]numberArray = new int[10];

// Do some initialisation...

Page 57: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

56

for (int index = 0; index < 10; index++){Console.WriteLine(numberArray[index]);

}

This will print out the values of each element in the array, starting from the element with index 0, up to the element with index 9 (n ot 10).

We can ask an array how long it is, giving us some more robust code (in the sense that if we changed the length of the array in the array creation statement, we don’t have to remember to change the value in the condition as well):

for (int index = 0; index < numberArray.Length; index++){Console.WriteLine(numberArray[index]);

}

If we try to use an index which is “out of bounds” (negative or greater than the index of the last element), the code will generate a so-called exception, indicating that an error occurred during the execution of the program.

The foreach-statement

Iterating through all elements of an array – or any type of collection – is a very common task in programming. So common, that a special type of repetition statement exists for that purpose; the foreach statement

Purpose; for each element in the collection, do a certain action.

Syntax (example):

foreach (int number in numberArray){Console.WriteLine(number);

}

Page 58: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

57

Here the variable number will take on the value of each of the elements in the collection – in this case, the type is int, but it can be anything.

It is syntactically simpler, and there is no risk of getting the initialization and/or condition wrong.

However, it is not as versatile as the general for-loop; use only in connection with processing of collections, and typically if we wish to do something for all the elements in the collection.

Lists

Arrays are useful, but they are a bit “old-school” in their style.

Fixed-size (or resize “manually”)Not much help with common tasks (insertion, search,…)

The .NET Framework Class Library – which is a large set of predefined classes available to the programmer – provides a number of classes for handling collections of objects (so-called collection classes), which provide methods for these tasks.

We do not need to worry about size issues; collections are automatically resized for us.

We have many methods available for us (Add, Clear, Remove,…)

One of the simplest of these collection classes is the List class.

When declaring a List object, we must provide the type of the elements in the list as a “parameter” to the List type:

List<int> numberList; // A list of integers

When we create a List object, we do n ot need to specify any size:

numberList = new List<int>();

Page 59: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

58

We can now call various methods on the List object, like

Add Clear Contains Count Remove…

Note that the List class actually uses an array “under the covers”.

Most common method is Add, this adds an element to the back of the list (list gets longer). We can use Insert to insert an element at a specific position

We get hold of an element in the same way as for arrays: we use the [] notation. Again index 0 for the first element!

numberList[2] // The element with index 2

The method Contains can tell us if a specific element is contained in the list:

// Is an element with value 77 in the list? numberList.Contains(77);

Many useful methods in the List class; see documentation or read in pop-up list.

Dictionary

The List class is a significant improvement of old-school arrays, but some tasks are still somewhat difficult.

We very often have classes where one instance field serves as a key to the data (i.e. uniquely identifies it). CPR for a person, license plate for a car, ISBN for a book, etc..

Very common task: Given the key, find the corresponding object.

Page 60: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

59

This is a bit hard to do efficiently when using lists; you have to search through the list step by step, until you either find the correct element, or can conclude that it is not there. Code must be explicitly written, and can be rather slow (has to search through much data).

The Dictionary class allows us to store a Key-Value relationship.

When declaring a Dictionary object, we must provide the type of the Key and the type of the Value as “parameters” to the Dictionary type:

// Key is String (CPR)// Value is Student object Dictionary<String, Student> students;

When we wish to add a Key-Value pair to the dictionary, we use the Add method, which now takes two parameters:

students.Add(“020388-1208”,aStudent);When we wish to remove something from the dictionary, we only need to providethe key!

students.Remove(“020388-1208”);

If we want to retrieve data about a student, we also only need to provide the key. The Dictionary class can then retrieve the data, and do so very efficiently!

The syntax is similar to the List syntax, but instead of a numerical index, we use the key value as index:

Student aStudent = students[“020388-1208”];

Note that if no student with that specific key exists, we get an error! We can use the method ContainsKey to check if the dictionary contains the key at all. If not, we should not try to look up the value in this way.

In general, you useList: if you can look up the data by numerical index, or do not have any particular need for looking up data

Page 61: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

60

Dictionary: If you need to look up data often, and there is a natural key for the data

Remember to check the documentation of available methods when using these classes

The concept of Inheritance

Another feature of OO is code reuse – we can (possibly) reuse code when we define new classes.

This allows us to implement class hierarchies in C#. A derived class should have anis-a relationship to the base class.

What is an is-a relationship? Consider the concepts Vehicle and Car. A car is definitely a special type of vehicle; in other words: a car i s a vehicle. So Car has an is- a relationship to Vehicle. This is different than the relationship between, say, Car and Wheel. A wheel is not a special type of car, but a car definitely has wheels. We say that Car has a has-a relationship to Wheel.

The mechanism for implementing an is-a relationship in code is the concept inheritance; a class may inherit from a base class, meaning that all methods and instance fields in the base class are also included in the derived class

Base Classes and Derived Classes

Syntax for a derived class:

// This class inherits from Student class GraduateStudent : Student{...

}

The derived class can use all public methods in the base class, just as any other user. It can n ot use private methods and instance fields, however!

Page 62: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

61

The access level protected allows usage by derived classes, but not by external users.

Tempting to make instance fields and methods protected, but not recommended! Potential problems:Base class “loses control” over instance fields, since the derived class can access and manipulate themDerived class may depend too much on representation

If the base class only has constructors that contain parameters, we must invoke the base class constructor from the derived class, providing the necessary parameters.

Syntax for calling base class constructors:

public GraduateStudent( string bachelorDegree, string name,int yearOfBirth): base(name, yearOfBirth){

this.bachelorDegree = bachelorDegree;}

Inheritance also allows us to replace (called “to override”) the implementation of a base class method with an alternative implementation in the derived class.

The base class must allow that a method can be overridden, by using the virtualkeyword:

// Implementation in Student (base) public virtual string GetName(){return name;

}

The derived class must also indicate that it is overriding the implementation, by using the keyword override:

Page 63: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

62

// Implementation in GraduateStudent (derived) public override string GetName(){return "Dr. " + base.GetName();

}

The Object Class

All classes in C# inherit – directly or indirectly – from a “mother of all classes” calledObject. This base class contains seven methods:

Equals Finalize GetHashCode GetTypeMemberwiseClone ReferenceEquals ToString

Some of these methods need to be overrided if we want a certain class to have certain abilities, like being able to store objects of that type in a hash-table based container (GetHashCode), to define equality in a non-trivial way (Equals), etc.

This is why we always have quite a lot of methods available on all objects in MSVS, since they all inherit methods from Object.

Page 64: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

63

Polymorphic variables and behavior

A great advantage of inheritance is co d e re use . Another great advantage is being able to program towards general (base) classes, instead of more specific (derived) classes. This makes it easy to extend code without much modification

OO Design Principle: Code should be closed for modification, but open for extension

Consider these classes:

Shape (has a virtual method Draw)Circle (inherits from Shape, overrides Draw)Triangle (inherits from Shape, overrides

Draw) Then is is legal code:

Shape shapeA = new Shape();Circle circleA = new Circle(); Triangle triA = new Triangle();

But also this!

Shape shapeA = new Shape(); Shape circleA = new Circle(); Shape triA = new Triangle();

Why is the last part interesting? Because we can then write code that does not know the true type of an object, but can still use its methods:

public void DrawAShape(Shape s){Console.WriteLine(“Now I draw something...”); s.Draw(); // What is s actually…?

}

Page 65: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

64

The true type of s may be e.g. Circle or Triangle, but the method does not need to know that!

The call of Draw on s may exhibit different behavior, depending on the actual type of s. This is known as p ol ym o r p h ic b e h a vi or ! (Polymorphic: many forms)

A further advantage is extensibility. If we need more shapes, we can just add them to the shape “package”, as long as they inherit from Shape. We will then n ot need to change the client code, since the client code only knows the base class. No modification, only extension.

Abstract methods and classes

A problem in the Shape class; what is a proper implementation of the Drawmethod…?

Do nothing, perhaps. Could work, but does it even make sense to create a Shapeobject…?

Not really; Shape is just a “common denominator” for shape-oriented classes, but aShape object in itself is not very useful.

By turning the Draw method into an a bs t r act method, we can achieve several advantages:We do not have to provide a (meaningless) implementation in the base class We cannot create any objects of the base classA derived class mu s t provide an implementation of the abstract method(s)

Note the difference between virtual and abstract:Virtual: h a s an implementation in the base class, can be overridden. Use when asensible implementation of the method exists for the base class.Abstract: h as n o implementation in the base class, mus t be overridden Use when no sensible implementation of the method exists for the base class.

If a class definition contains just one abstract method, the whole class also becomes abstract.

Page 66: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

50

Interfaces

We may be in a situation where a l l methods in a class should be abstract. Such a class is called an interface.

Interfaces are used quite heavily in C#. Think of an interface as a “contract” – the interface defines the methods available in any implementation of the interface, and should also include a description of the functionality that should be expected. It does however n ot provide any specific implementation.

Interfaces follow a slightly different syntax:

public interface IShape{void Draw();

}

Usually starts with an IUses the keyword interface instead of classAll methods are public (but we do not write “public”!) No instance fields

Advantages are the same as before (allows polymorphic behavior), just taken to the extreme. Two classes that both implement the interface may be completely unrelated with regards to implementation.

The C# class library contains many interfaces in itself, e.g. IComparable

Page 67: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

51

Defensive Programming

In real-life scenarios, we have to prepare for unexpected data values and exceptional situations in general

What can go wrong? Some examples:

Value is correct type-wise, but is outside the range of meaningful values (example: A test score is supposed to be between 0 and 100, but an int can represent many other values, like e.g. -27, 22987)

Value is used for indexing an array – only values from 0 (zero) up to (length – 1) are meaningful. Other values will produce an error

A string does not follow a given syntax (e.g. for a license plate) A variable that is supposed to refer to an object has the value null instead A file contains data that has a different format than expected, or the file is

missing A database is for some reason unavailable An Internet connection is for some reason unavailable

The action of the program in the above cases is of course situation-dependent. Program may halt, show an error message, silently handle the error, fall back to a default value, etc.

In any case, we should be prepared for handling all possible situations in a graceful manner.

In practice, we then have to validate all critical variables before they are used.

When should we validate? Early: As soon as the variable has the value that will be used in a critical

Situation Late: Just before the variable is actually used

When to validate is also situational-dependent. Argument against early validation could be that value might not be used at all.

Page 68: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

52

We detect an error during program execution – now what? Management of errors can be broken down into several tasks:

Detection – realising that an error situation has occurred Signaling – making the surrounding code aware that an error has been

detected Capturing – taking responsibility for handling of the error Handling – actually performing the error handling actions

All these actions can be distributed in the code. This may imply that the detecting part of the code does n ot know how to handle the error!

Problems to consider How do we signal an error? How do we capture an error? What should happen after the error has been handled?

The mechanism for managing errors in C# - and many other OO-languages – is through exceptions

Exceptions - throw

An exception is in itself “just another class”

An exception object is created just as any other object; use new and the proper class

The interesting part: We can throw and catch exceptions.

If an “exceptional situation” (an error) occurs, the code can throw an exception:

public void deposit(int amount){if (amount < 0){

NegativeAmountException ex =new NegativeAmountException(“...”);

throw ex;}

balance = balance + amount;

Page 69: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

53

}

Note the use of the throw keyword.

As soon as an exception is thrown, no more code in the method is executed!

We throw because we do n ot know how to handle the error!

Exceptions - catch

Throwing an exception signals to the outside world that an error has occurred.

The part of the code that wishes to capture the error must catch the

exception!

Code that might throw an exception should be executed within a so-called try-catchblock:

BankAccount myAcc = new BankAccount();

try{

int amount = ...; // From user myAcc.deposit(amount);

}catch (NegativeAmountException ex){

Console.WriteLine(“Negative amount not allowed”);}

Caller is aware that an exception may occur, and decides how to handle it.

General principle: Throw early, catch late

Throw as soon as an error is detectedOnly catch if you really know how to handle the error (tempting just to silently “consume” the error)

Page 70: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

54

Exceptions - catch

What code is executed after the catch-part has been executed?

Control does not return to the code that threw the exception; it returns to the first statement after the catch-block. More precisely after the l a s t catch-block, since you can have several catch-blocks, handling different exceptions.

This may cause problems, if the code that threw the exception has claimed some system resources, like opening a file.

How can we make sure that e.g. a file is closed, regardless of whether or not an exception has occurred?

In C#, a finally clause is used for this purpose. Code placed in a finally-block is g u a r a n te e d to be executed, exception or not.

try{theFile.open(fileName);... // File processing

}catch (IOException ex){Console.WriteLine(“File processing failed...”);

}finally{theFile.close();

}

Code for releasing resources should be in a finally-block.

Page 71: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

55

Exceptions - details

A lot of the methods in the class library may throw exceptions. Just dividing by zero will cause an exception!

How can we learn which exceptions a method may throw? Look in the documentation! Documenting exceptions is also an important part of the documen- tation of your own code.

C# contains a class hierarchy of exception classes – the base class is calledException.

Use the built-in exception classes if they are appropriate; otherwise create your own exception classes. Your own exception classes m u s t inherit from an existing exception class, since you can only throw an object which inherit from Exception

An exception object has a number of properties, which provide more information about the nature of the exception, for instance the Message property. See the documentation for further information.

Should I a l wa y s throw exceptions in case of errors? No, not if you are absolutely sure how the error should be handled.

Remember to consider architectural issues; it may be unwise to present an error to a user in a GUI-specific manner inside a business-logic class.

Page 72: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

56

Constants

Suppose we wish to create a program for a simple simulation of an eco-system. Many parameters to decide on:

Size of simulation grid (x,y) Initial number of predators Initial number of prey Breeding rates…

All these values will be constant throughout the execution of the program, so they can be set directly in the code

for (int x = 0; x < 50; x++){for (int y = 0; y < 40; y++){// Do something for each cell…

}}

The values might occur many times in the code, e.g. every time we have to do something for the entire grid. There are problems with this approach:Hard to read the code – what does the value 50 mean in a specific context?If we wish to change the value, we will have to do it in each and every place. We could forget some places…

Much more convenient to use constants instead

A constant is a variable that has a fixed value (hardly a variable then…).

Declaration of constants:

public class EcoSimulation{

public const int gridWidth = 50; public const int gridHeigth = 40;

Page 73: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

57

Using constants

for (int x = 0; x < gridWidth; x++){for (int y = 0; y < gridHeigth; y++){

// Do something for each cell…}

}

Much easier to understand the code, if the constants have meaningful names. If we need to change e.g. the grid width, we only have to change it in o n e place.

General principle in programming; we do not want to specify the same information more than once! Analogous with Headings, etc. in Word – an extra layer of indirection.

Static methods and classes

The standard way of using a class is to:Create an object of the class, using the new keywordCall methods on the object

However, if the class does not contain any kind of state – and thus no instance variables – there is not really any need to create objects, since we cannot change their state.

In that case, we can make the class a static class.

static class StringMethods{public static String GetStringSubsection(String s, int start, int end);

public static String GetLetterCount(String letter);…

Page 74: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

58

When we wish to use the methods in the class, we use this syntax:

int bCount = StringMethods.GetLetterCount(“b”);

Here we do n ot have to use new; we just type the na m e of the class, followed by the dot, followed by the name of the method

Note that if we make the entire class static, it can only contain static methods. However, we can also declare methods in an ordinary (non-static) class to be static. This is typically done for methods that do not use or alter the state of the object

It is also possible to define an instance variable to be static. No matter how many objects we then create of that class, there will still only be one instance of that variable; it is “shared” among the objects.

Example could be to keep track of the number of objects that have been created of a given class; define a static instance field, and increase it by one in the class constructor, which is executed whenever a new object is created.

Static and non-static elements can be mixed in these ways:A static class can o n ly contain static methods and static instance variablesA non-static class can contain b oth static and non-static methods and instance variablesA static method can o n ly use static instance fieldsA non-static method can use b o th static and non-static instance variables

A lot of (static) methods are e.g. found in the Math class (part of the .NET class library)

Actually, you have used static classes and methods from day 1. Think ofConsole.WriteLine(…)

Page 75: heho-easj.dkheho-easj.dk/SWC1-2015e/CsharpNote.docx · Web viewheho-easj.dk

59

Enumerations

The primitive types available in C# are often not exactly what we want. Suppose we wish to make a program that deals with fruit, say these five kinds of fruit: Apple, Pear, Cherry, Banana and Kiwi. How do we represent a fruit?

As a bool: Impossible, only two possible valuesAs an int: Possible (say values 1 to 5), but not very convenient. We have to check for legal values, and code can be hard to understand (maybe use constants…?)As a String: Possible, but again we need to check for legal values

What we would really like is a type that can only hold exactly the five values given above. We cannot then specify a wrong value. This can be done using an enumerated type.

class Fruit{

public enum FruitType { Apple, Pear, Cherry, Banana, Kiwi};

We can now declare a variable of this type (syntax is slightly awkward, notice the use of “dot”):

Fruit.FruitType aFruit = Fruit.FruitType.Apple;

The point is: We can n e v er assign a wrong value to the variable, since the type itself specifies the legal values. Errors are caught at compile-time, not at run-time.