developmentor - a developer services company				  
				      C# Tutorial
   Modules

Basics


Goals:

  • Introduce the basics of a class.
  • Describe the Main method.
  • Survey types, variables, arrays, operators, control constructs, and comments.
  • Show how to perform text based input and output.

Overview

We will now introduce the core of the C# language; that is, we will cover the features that every program will need to use. Most of this section will be a relatively straightforward examination of syntax so you may need to practice a bit of delayed gratification - we'll get to cooler stuff very soon.


Class

A class is the primary way for the C# developer to create a new data type. The definition syntax is the keyword class, the class name, and then curly braces enclosing the class body.

A class typically contains two types of things: variables (i.e. data) and methods (i.e. functions). All variables and methods must be members of some type because the language does not allow global variables or global methods. For now, we will keep things simple and create classes that contain just the Main method. We will expand on the capabilities of a class in later chapters.

Note that there are several other ways to create new types: struct, enum, delegate, and interface; however, each of these are more specialized than class.


Main method

The Main method defines the application entry point. The name is case sensitive so the capital M is required. Main must be a static method of some class. We will discuss the meaning of static in a later chapter.

In addition to serving as the application entry point, Main can also interact with the environment. Main can take an array of strings as its argument. The strings will be obtained from the command line when the program is invoked.

Main can also return an int code back to the invoking environment. The return code is most often used to indicate the success or failure of the program execution. Traditionally, a return value of zero indicates success while non-zero values are used as error codes to indicate failure.

Environment interaction is not extremely common in these days of graphical user interfaces. However, some application categories such as development tools (compilers and linkers) still use command line interfaces.


Simple types

The set of core types offered by C# are called the simple types. These are analogous to what other languages call built-in types or primitive types.

There is a Boolean type named bool which can take on only two values: true and false.

The character type is 16 bit Unicode. Character literals are enclosed in single quotes; for example, a capital A would be written as 'A'. A less common but interesting special case allows a character to be specified by giving the hexadecimal or Unicode value. The capital A character has a Unicode value of 65 (hex 0041) so it could be written as either '\u0041' or '\x0041'.

There are several different flavors of integer that vary by size and by whether they are signed or unsigned. Signed types can store both positive and negative values while unsigned types store only positive numbers. Common practice is to use int as the primary integer type since 32 bits is usually large enough for most needs and a signed quantity is typically preferred.

There are three different sizes of floating point types: float, double, and decimal. The 64-bit type double is the most commonly used of the three. The float type is only 32 bits and so is often considered too small for any application that does serious floating point arithmetic. The decimal type provides extremely high precision at the expense of range and so is intended for specialized financial and scientific calculations.

The string type represents a sequence of characters. String literals are enclosed in double quotes.


Local variables

Local variables are declared inside a method and are only accessible inside the method body. The declaration syntax is type name followed by comma separated list of variables with a semicolon ending the statement.

Local variables can optionally be given an initial value when they are declared. The initialization syntax is the assignment operator = followed by the initial value. The initial value can be a literal or an expression.

Local variables must be assigned to before they can be used. The compiler tracks the state of all local variables and rejects any attempt to use them before they have been given a value. This is an extremely nice service provided by the compiler and should help to eliminate an entire category of program bugs.


Type conversion

It is occasionally necessary to convert a value from one simple type to another; for example, converting from int to long or from double to int. These conversions fall into two categories: implicit and explicit. An implicit conversion happens automatically and there is no need for any special action on the part of the programmer. On the other hand, an explicit conversion requires that the programmer explicitly request the change by adding a cast to their code. The cast syntax is the destination type name enclosed in parentheses. In general, conversions that could lose information require an explicit cast. For example, a cast is needed to convert double to float, float to int, or long to int.


Console input and output

C# console applications interact with the user through a text based console window. The .NET Framework Class Library provides a class named Console to facilitate console IO. The Console class is part of the System namespace.

The simplest way to read input is using the ReadLine method which reads an entire line of input at once. The result is a string containing the entire input line.

If more control over input is needed, the Read method can be used to read each input character one at a time.

After reading the user input, the next step is to get it into the desired form. If the user is entering a string value such as their name, then you are done since the input data is already a string. However, if the user is entering a numeric value such as their age or salary, then the input string must be converted to a numeric form. The .NET Framework Class Library supplies a class named Convert that can perform most commonly needed conversions. The Convert class is in the System namespace.

The Console class also supplies output methods. There are several methods named WriteLine that write various data types to the console. In addition to writing the data, WriteLine adds a line terminator to the output so any subsequent output will appear on a new line.

There is a fancier version of WriteLine that allows multiple values to be printed in a single call. The first argument is a format string which contains some literal text and some special symbols called format specifiers. The format specifiers act as placeholders and will be replaced with actual values during printing. A format specifier is written as an integer inside curly braces (e.g. {0} or {1}). After the format string come additional arguments, typically one for each format specifier in the format string. The additional arguments are numbered starting at zero. During printing, the format specifiers are replaced with the value of the corresponding argument.

The Console class also offers a set of methods name Write that work just like WriteLine except that they do not add a line terminator to the output.


Namespace

A namespace represents a logical group of types. The .NET Framework Class Library makes heavy use of namespaces to partition it into smaller pieces that are easier for users to handle. The core of the library is gathered into a namespace called System. To access the members of a namespace, you use the namespace name and then the dot operator as a separator.

Prefixing each use of a library component with the namespace name quickly becomes tedious and makes the code unnecessarily verbose. A using directive can be used to obtain shorthand access to the components of a namespace. The using directive is typically placed at the top of source file. The syntax consists of the keyword using, the namespace name, and a semicolon.


Arithmetic operators

A comprehensive set of arithmetic operators are available. The standard +, -, *, and / operators are present. A slightly more interesting offering is the remainder operator (%) which computes the remainder of integer division. In addition, there are some specialized operators which manipulate the binary representation of a variable

Each arithmetic operator has a corresponding combination assignment version that does two things at once: it performs the arithmetic and assigns the result. For example, the combination operator for addition is +=.

The designers of the C language family (C, C++, Java, C#) seem to have agreed that providing such combination operators is desirable since there are quite a few of them available.

There are two specialized operators to perform the increment (++) and decrement (--) operations. The basic use of these operators is extremely simple: they add or subtract 1 from the variable to which they are applied.

It turns out that the increment and decrement operators are slightly more powerful (and subtle) then they at first appear. The operators can actually be placed on either side of a variable and they have a slightly different effect in the two different positions. This added ability only comes into play when the increment/decrement is used as part of a larger expression. In that case, the position of the operator determines when the increment/decrement is performed.

When the operator is placed in front of the variable the operation is performed first, before the variable is used in the larger expression. This is called pre-increment or pre-decrement.

When the operator is placed after the variable the operation is performed second; that is, after the variable is used in the larger expression. This is called post-increment or post-decrement.

Finally, there is the somewhat cryptic conditional operator ?: that provides a shorthand way of writing an if-then-else statement. The ? and the : serve as delimiters between the three operands. The first operand is a Boolean expression. The Boolean expression is evaluated, if true, the result is the expression after the ? otherwise the result is the expression after the :.


Comments

There are two primary comment styles: multi line and single line. A multi line comment is delimited beginning with /* and ending with */. A single line comment begins with // and extends to the end of the line.

There is one additional type of comment that you might see called a documentation comment. The documentation comment contains XML that serves to document the code for users. The C# compiler provides a /doc switch to build an XML file from the documentation comments.


Array

Arrays provide efficient storage for multiple data elements. An array is specified using square brackets [ ] and must be created using the new operator. To create an array, both the element type and the length must be specified.

Array elements are accessed using [ ] and the desired index. Indices start at 0, so the valid indices for a length 5 array are 0, 1, 2, 3, 4. Bounds checking is performed to prevent access to memory outside the array. If an invalid index is used, the CLR traps the error and generates an exception of type IndexOutOfRangeException. The bounds checking is performed at runtime and does add a small amount of overhead; however, the designers of the CLR thought that the added program safety and robustness were well worth the time.

The length of an array is fixed at the point it is created and it cannot be resized. For convenience, the length of an array is recorded in its Length property which can be accessed using the dot operator.

When an array is first created, each element is set to a default value based on its type. For all the numeric types such as int, double, etc. the default value is 0. For other types the story is a bit more interesting: an array of bool has each element set to false and an array of characters starts with each element set to the null character (0x0000).


if else statement

The primary way to perform conditional execution is with an if statement. An if statement has an associated Boolean expression and a statement: if the Boolean expression is true then the statement is executed; otherwise, the statement is skipped. C# is case sensitive so if must appear in lower case. Also note that the parentheses around the Boolean expression are required.

An if statement can optionally contain an else part. The statement associated with the else part gets executed only if the expression is false.


Boolean operators

Boolean expressions are built using the comparison and logical operators. The comparison operators provide ways to test common properties such as equal, greater than, less than, etc. The logical operators perform the Boolean logic functions and, or, not.


Code block

Most of the control constructs such as the if statement and the loops permit only a single statement as their body. Placing multiple statements is an error.

In order to associate multiple actions with a control construct, the statements must be placed inside curly braces. The curly braces form what is sometimes called a compound statement or a code block.


switch statement

A switch statement performs selection from a fixed set of options. It consists of an expression followed by a set of cases. The expression is evaluated and the result compared against each case. If a match is found, the code associated with that case is executed. If no match is found, the default case is executed. The default case is completely optional.

A break is required to mark the end of each case that contains associated code. It is a compile time error if the break is omitted.

It is possible to associate multiple options with a single action by placing the cases one after the other with no intervening code. Note that it is legal to omit the break from a case if it does not have any associated code; this fact is crucial in understanding why multiple labels are allowed and only a single break is required at the end of the entire construct.


Loops

C# offers 4 loops: while, do, for, and foreach.

A while loop is the most basic looping construct. It consists of the keyword while followed by a Boolean expression and then a statement or code block. As long as the Boolean expression continues to evaluate to true, the associated code will get executed.

A do loop is both more complicated and less useful than a while loop. It consists of the keyword do, a statement or code block that forms the body of the loop, the keyword while, a Boolean expression, and a semicolon to end the whole construct. The odd thing about the do loop is that the test condition is at the bottom of the loop. When the loop begins to run, the test is not evaluated so the body is executed immediately. Only after the body is executed is the test evaluated. If the test is evaluates to true, then the process repeats; otherwise the loop ends. This behavior means that the body of a do loop is always executed at least once.

A for loop has three parts separated by semicolons. The first part is used for initialization and is performed only once when the loop first begins execution. The second part is the test condition used to determine if the loop should continue to run. The third part is executed after each iteration and so is typically used to increment a loop counter.

A foreach loop is a specialized construct for use with collections of data such as arrays. The syntax and use is simple and very readable: the keyword foreach, an open parenthesis, the type of data stored in the collection, a variable name used to hold each successive value from the collection, the keyword in, the collection to be traversed, a close parenthesis, and finally the loop body. The loop body is executed once for each element in the collection.

The keyword break can be used to exit any of the loops before the loop would normally terminate. break is most often used to abort processing if an error occurs.

This material is excerpted from the Programming C# course offered by DevelopMentor.