Microsoft.NET

……………………………………………….Expertise in .NET Technologies

C# Language Fundamentals

Posted by Ravi Varma Thumati on March 16, 2009

 

This chapter discusses the type system in C#, drawing a distinction between built-in types (int, bool, etc.) versus user-defined types (types you create as classes and interfaces). The chapter also covers programming fundamentals such as how to create and use variables and constants. It then goes on to introduce enumerations, strings, identifiers, expressions, and statements.

 

The second part of the chapter explains and demonstrates the use of flow control statements, using if, switch, while, do...while, for, and foreach statements. Also discussed are operators, including the assignment, logical, relational, and mathematical operators.

Types

 

C# is a strongly typed language. In a strongly typed language you must declare the type of each object you create (e.g., integers, floats, strings, windows, buttons, etc.), and the compiler will help you prevent bugs by enforcing that only data of the right type is assigned to those objects. The type of an object signals to the compiler the size of that object.

 

Like C++ and Java, C# divides types into two sets: intrinsic (built-in) types that the language offers and user-defined types that the programmer defines.

 

C# also divides the set of types into two other categories: value types and reference types.The principal difference between value and reference types is the manner in which their values are stored in memory. A value type holds its actual value in memory allocated on the stack (or it is allocated as part of a larger reference type object). The address of a reference type variable sits on the stack, but the actual object is stored on the heap.

 

Working with Built-in Types

 

The C# language offers the usual cornucopia of intrinsic (built-in) types one expects in a modern language, each of which maps to an underlying type supported by the .NET CLS. Mapping the C# primitive types to the underlying .NET type ensures that objects created in C# can be used interchangeably with objects created in any other language compliant with the .NET CLS, such as VB.NET.

 

Table 3-1. C# built-in value types

Type

Size (in bytes)

.NET type

Description

byte

 

1

 

Byte

 

Unsigned (values 0-255).

char

 

2

 

Char

 

Unicode characters.

bool

 

1

 

Boolean

 

True or false.

sbyte

 

1

 

SByte

 

Signed (values -128 to 127).

short

 

2

 

Int16

 

Signed (short) (values -32,768 to 32,767).

ushort

 

2

 

UInt16

 

Unsigned (short) (values 0 to 65,535).

int

 

4

 

Int32

 

Signed integer values between -2,147,483,648 and 2,147,483,647.

uint

 

4

 

UInt32

 

Unsigned integer values between 0 and 4,294,967,295.

float

 

4

 

Single

 

Floating-point number. Holds the values from approximately +/-1.5 * 10-45 to approximately +/-3.4 * 1038 with seven significant figures.

double

 

8

 

Double

 

Double-precision floating point. Holds the values from approximately +/-5.0 * 10-324 to approximately +/-1.8 * 10308 with 15-16 significant figures.

decimal

 

16

 

Decimal

 

Fixed-precision up to 28 digits and the position of the decimal point. This is typically used in financial calculations. Requires the suffix “m” or “M.”

long

 

8

 

Int64

 

Signed integers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

ulong

 

8

 

UInt64

 

Unsigned integers ranging from 0 to 0xffffffffffffffff.

 

Converting built-in types

Objects of one type can be converted into objects of another type either implicitly or explicitly. Implicit conversions happen automatically; the compiler takes care of it for you. Explicit conversions happen when you “cast” a value to a different type.

Implicit conversions happen automatically and are guaranteed not to lose information. For example, you can implicitly cast from a short int (2 bytes) to an int (4 bytes). No matter what value is in the short, it is not lost when converting to an int:

short x = 5;
int y = x; // implicit conversion

 

If you convert the other way, however, you certainly can lose information. If the value in the int is greater than 32,767, it will be truncated in the conversion. The compiler will not perform an implicit conversion from int to short:

short x;
int y = 500;
x = y;  // won't compile

 

You must explicitly convert using the cast operator:

short x;
int y = 500;
x = (short) y;  // OK

Variables and Constants

Variables

 

A variable is a programming language abstraction that represents a storage location. A C# variable has the following attributes:

 

·          Name: The name of a variable is the label used to identify a variable in the text of a program.

 

·          Type: The type of a variable determines the set of values that the variable can have and the set of operations that can be performed on that variable.

 

·          Value: The value of a variable is the content of the memory location(s) occupied by that variable. How the contents of the memory locations are interpreted is determined by the type of the variable.

 

·          Lifetime: The lifetime of a variable is the interval of time in the execution of a C# program during which a variable is said to exist. Local variables exist as long as the method in which they are declared is active. Non-static fields of a class exist as long as the object of which they are members exist. Static fields of a class exist as long as the class in which they are defined remains loaded in the C# common language runtime.

 

·          Scope: The scope of a variable is the range of statements in the text of a program in which that variable can be referenced.

 

Consider the C# variable declaration statement:

int i = 57;

 

This statement defines a variable and binds various attributes with that variable. The name of the variable is i, the type of the variable is int, and its initial value is 57.

 

Some attributes of a variable, such its name and type, are bound at compile time. This is called static binding. Other attributes of a variable, such as its value, may be bound at run time. This is called dynamic binding.

 

There are two kinds of C# variables–local variables and fields. A local variable   is a variable declared inside a method. A field is a variable declared in some struct or class. (Classes are discussed in Section).

 

A variable is a storage location with a type. In the preceding examples, both x and y are variables. Variables can have values assigned to them, and those values can be changed programmatically.

Create a variable by declaring its type and then giving it a name. You can initialize the variable when you declare it, and you can assign a new value to that variable at any time, changing the value held in the variable. This is illustrated in Example 3-1.

Example 3-1. Initializing and assigning a value to a variable
#region Using directives
 
using System;
using System.Collections.Generic;
using System.Text;
 
#endregion
 
namespace InitializingVariables
{
   class Values
   {
      static void Main( )
      {
 
         int myInt = 7;
         System.Console.WriteLine("Initialized, myInt: {0}",
            myInt);
 
         myInt = 5;
         System.Console.WriteLine("After assignment, myInt: {0}",
            myInt);
 
      }   
   }
}
 
Output:
Initialized, myInt: 7
After assignment, myInt: 5

Here we initialize the variable myInt to the value 7, display that value, reassign the variable with the value 5, and display it again.

Definite Assignment

C# requires definite assignment: that is, variables must be initialized or assigned to before they are used. To test this rule, change the line that initializes myInt in Example 3-1 to:

int myInt;
Example 3-2. Using an uninitialized variable
#region Using directives
 
using System;
using System.Collections.Generic;
using System.Text;
 
#endregion
 
namespace UninitializedVariable
{
   class UninitializedVariable
   {
      static void Main(string[] args)
      {
         int myInt;
         System.Console.WriteLine
         ("Uninitialized, myInt: {0}", myInt);
         myInt = 5;
         System.Console.WriteLine("Assigned, myInt: {0}", myInt);
 
      }
   }
}

When you try to compile this listing, the C# compiler will display an error message.

Constants

 
A constant is a variable whose value can't be changed. Variables are a powerful tool, but there are times when you want to manipulate a defined value, one whose value you want to ensure remains constant. 

Constants come in three flavors: literals , symbolic constants, and enumerations. In this assignment:

x = 32;

the value 32 is a literal constant. The value of 32 is always 32. You can’t assign a new value to 32; you can’t make 32 represent the value 99 no matter how you might try.

Symbolic constants assign a name to a constant value. You declare a symbolic constant using the const keyword and the following syntax:

const type identifier = value;

A constant must be initialized when it is declared, and once initialized it can’t be altered. For example:

const int FreezingPoint = 32;

In this declaration, 32 is a literal constant and FreezingPoint is a symbolic constant of type int. Example 3-4 illustrates the use of symbolic constants.

Example 3-4. Using symbolic constants
#region Using directives
 
using System;
using System.Collections.Generic;
using System.Text;
 
#endregion
 
namespace SymbolicConstants
{
   class SymbolicConstants
   {
      static void Main(string[] args)
      {
         const int FreezingPoint = 32;   // degrees Fahrenheit
         const int BoilingPoint = 212;
 
         System.Console.WriteLine("Freezing point of water: {0}",
              FreezingPoint);
         System.Console.WriteLine("Boiling point of water: {0}",
              BoilingPoint);
 
         BoilingPoint = 21;
 
      }
   }
}

Enumerations

Enumerations provide a powerful alternative to constants. An enumeration is a distinct value type, consisting of a set of named constants (called the enumerator list).

In Example 3-4, you created two related constants:

const int FreezingPoint = 32;  
const int BoilingPoint = 212;

 

You might wish to add a number of other useful constants to this list, such as:

const int LightJacketWeather = 60;
const int SwimmingWeather = 72;
const int WickedCold = 0;

 

This process is somewhat cumbersome, and there is no logical connection between these various constants. C# provides the enumeration to solve these problems:

enum Temperatures
{
   WickedCold = 0,
   FreezingPoint = 32,
   LightJacketWeather = 60,
   SwimmingWeather = 72,
   BoilingPoint = 212,
}

 

Every enumeration has an underlying type, which can be any integral type (integer, short, long, etc.) except for char. The technical definition of an enumeration is:

[attributes] [modifiers] enum identifier 
     [:base-type] {enumerator-list};

The optional attributes and modifiers are considered later in this book. For now, let’s focus on the rest of this declaration. An enumeration begins with the keyword enum, which is generally followed by an identifier, such as:

enum Temperatures

The base type is the underlying type for the enumeration. If you leave out this optional value (and often you will), it defaults to int, but you are free to use any of the integral types (e.g., ushort, long) except for char. For example, the following fragment declares an enumeration of unsigned integers (uint):

enum ServingSizes :uint
{
    Small = 1,
    Regular = 2,
    Large = 3
}

Notice that an enum declaration ends with the enumerator list. The enumerator list contains the constant assignments for the enumeration, each separated by a comma.

Example 3-5 rewrites Example 3-4 to use an enumeration.

Example 3-5. Using enumerations to simplify your code
#region Using directives
 
using System;
using System.Collections.Generic;
using System.Text;
 
#endregion
 
namespace EnumeratedConstants
{
   class EnumeratedConstants
   {
 
      enum Temperatures
      {
         WickedCold = 0,
         FreezingPoint = 32,
         LightJacketWeather = 60,
         SwimmingWeather = 72,
         BoilingPoint = 212,
      }
 
      static void Main(string[] args)
      {
         System.Console.WriteLine("Freezing point of water: {0}",
            (int)Temperatures.FreezingPoint);
         System.Console.WriteLine("Boiling point of water: {0}",
            (int)Temperatures.BoilingPoint);
      }
   }
}

As you can see, an enum must be qualified by its enumtype (e.g., Temperatures.WickedCold). By default, an enumeration value is displayed using its symbolic name (such as BoilingPoint or FreezingPoint). When you want to display the value of an enumerated constant, you must cast the constant to its underlying type (int). The integer value is passed to WriteLine, and that value is displayed.

Each constant in an enumeration corresponds to a numerical valuein this case, an integer. If you don’t specifically set it otherwise, the enumeration begins at 0 and each subsequent value counts up from the previous.

If you create the following enumeration:

enum SomeValues
{
   First,
   Second,
   Third = 20,
   Fourth
}

the value of First will be 0, Second will be 1, Third will be 20, and Fourth will be 21.

Enums are formal types; therefore an explicit conversion is required to convert between an enum type and an integral type.

Strings

It is nearly impossible to write a C# program without creating strings. A string object holds a string of characters.

You declare a string variable using the string keyword much as you would create an instance of any object:

string myString;

A string literal is created by placing double quotes around a string of letters:

"Hello World"

It is common to initialize a string variable with a string literal:

string myString = "Hello World";

Identifiers

Identifiers are names programmers choose for their types, methods, variables, constants, objects, and so forth. An identifier must begin with a letter or an underscore.

The Microsoft naming conventions suggest using camel notation (initial lowercase such as someName) for variable names and Pascal notation (initial uppercase such as SomeOtherName) for method names and most other identifiers.

Expressions

Statements that evaluate to a value are called expressions. You may be surprised how many statements do evaluate to a value. For example, an assignment such as:

myVariable = 57;

is an expression; it evaluates to the value assigned, which, in this case, is 57.

Note that the preceding statement assigns the value 57 to the variable myVariable. The assignment operator (=) doesn’t test equality; rather it causes whatever is on the right side (57) to be assigned to whatever is on the left side (myVariable). All the C# operators (including assignment and equality) are discussed later in this chapter (see “Operators”).

Because myVariable = 57 is an expression that evaluates to 57, it can be used as part of another assignment operator, such as:

mySecondVariable = myVariable = 57;

 

What happens in this statement is that the literal value 57 is assigned to the variable myVariable. The value of that assignment (57) is then assigned to the second variable, mySecondVariable. Thus, the value 57 is assigned to both variables. You can therefore initialize any number of variables to the same value with one statement:

a = b = c = d = e = 20;

Whitespace

In the C# language, spaces, tabs, and newlines are considered to be “whitespace” (so named because you see only the white of the underlying “page”). Extra whitespace is generally ignored in C# statements. You can write:

myVariable = 5;

or:

myVariable    =                             5;

and the compiler will treat the two statements as identical.

The exception to this rule is that whitespace within strings isn’t ignored. If you write:

Console.WriteLine("Hello World")

each space between “Hello” and “World” is treated as another character in the string.

Most of the time the use of whitespace is intuitive. The key is to use whitespace to make the program more readable to the programmer; the compiler is indifferent.

However, there are instances in which the use of whitespace is quite significant. Although the expression:

int x = 5;

is the same as:

int x=5;

 

Statements

In C# a complete program instruction is called a statement. Programs consist of sequences of C# statements. Each statement must end with a semicolon (;). For example:

int x;     // a statement
x = 23;    // another statement
int y = x; // yet another statement
 

Unconditional Branching Statements

An unconditional branch is created in one of two ways. The first way is by invoking a method. When the compiler encounters the name of a method, it stops execution in the current method and branches to the newly “called” method. When that method returns a value, execution picks up in the original method on the line just below the method call. Example 3-6 illustrates.

Example 3-6. Calling a method
#region Using directives
 
using System;
using System.Collections.Generic;
using System.Text;
 
#endregion
 
namespace CallingAMethod
{
   class CallingAMethod
   {
      static void Main( )
      {
         Console.WriteLine("In Main! Calling SomeMethod( )...");
         SomeMethod( );
         Console.WriteLine("Back in Main( ).");
      }
      static void SomeMethod( )
      {
         Console.WriteLine("Greetings from SomeMethod!");
      }
   }
}
Output:
In Main! Calling SomeMethod( )...
Greetings from SomeMethod!
Back in Main( ).

Program flow begins in Main( ) and proceeds until SomeMethod() is invoked (invoking a method is sometimes referred to as “calling” the method). At that point, program flow branches to the method. When the method completes, program flow resumes at the next line after the call to that method.

The second way to create an unconditional branch is with one of the unconditional branch keywords: goto, break, continue, return, or throw. Additional information about the first three jump statements is provided later in this chapter; the return statement returns control to the calling method; the final statement

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: