Enumerations

Enums (short for Enumerations) are a set of named numeric constants. They are useful when some value in a program can have a specific set of values. Suppose we want our program to accept only three values such as Pizza, Pasta and Spaghetti as the food type. We can easily enforce this by specifying an enum (foodType), which consists of the specified values, and write a method that accepts only this enum as a parameter. This is shown in Example 17.

Example 17:

Enumerators Example 17

Enumerations in C#, as in the case of C/C++, have numbers associated with the values. By default, the first element of the enum is assigned a value of 0 and is incremented for each subsequent enum element. However, if you wish to override this and specify your own values you can very well do so at the initialization stage. Thus, Example 17 cab be modified as shown in Example 18.

Example 18:

Enumerators Example 18

Structs

Classes are great for implementing objects. However, there may be times when you feel that an object should behave like one of the built-in types, something fast to allocate without much of an overload, and overhead of references. The answer is to use structs (short for Structures). Unlike the structs of C/C++, the structures in C# can have methods defined within them. They can have a constructor too.

Consider the following example,

Example 16:

Structs Example 16

As you can see we have a constructor, a method, and a data member in our structure TestStruct. Recall that in C/C++ we could only have data members in structures. No methods or constructors were allowed.

If structs can have methods and constructors then how are they different from classes is a good question to ask. Structs do have their own restrictions. They cannot implement inheritance. Secondly and most importantly structs are of value types while classes are of reference types. Structs are stored in a stack while classes on a heap!

In C# the simple types are actually structs that can be found in the System namespace. For example, the long type is an alias for System.Int64 struct. This means that when you are working with simple types you are actually working with the structs in the base class.

Arrays

Arrays are a group of values of similar data types. These values are stored in continuous memory locations, thereby, making it easier to access and manipulate the values. Arrays in C# belong to the reference type and hence are stored on the heap. The declaration of arrays in C# follow the syntax given below:

DataType[number of elements] VariableName;

For example,

int[6] arr1;

In the above example, we have specified the number of elements the array will consist of, However, this is optional in C#. This means that the number of elements in the array can be assigned later in the program. For example,

int[] arr2;
arr2 = new int[9];

The initialization of an array can be done when it is declared or at a later stage in the program. The initialization of the array at the declaration stage is done in the following manner:

int[] arr3 = {0,1,2};

Data Types in C#

C# provides us with an Unified Type System. This means that all data types in C#, be it a reference type of value type, are derived from just one class, the object class. It simply means that the object class is the ultimate base class for all data types. This is actually great news. It means that literally everything in C# is an object since all types are derived from the object class.

Consider the following example:

Example 14:

Example14

Observe the line 7 in Example 14. It is something we have not come across in any programming language. After all 9 is a number how can it have a method? But no! This is the C# realm, where everything is an object! Even the number 9! It has methods of which we have shown one, the ToString() method. This method converts the number to a string. The code will execute without any errors and will store the number 9 as a string in the variable CheckThis as expected. Astounding isn’t it? One more exciting thing about C# is that since all types are derived from a common class (namely object) they all have similar characteristics.

Static members

Sometimes it is necessary to define members in a class that are not associated with any particular object other than the class itself. This means that there will be only one instance of this method/field no matter how many objects of the class exist.

Static members can be defined in C# by using the keyword static, as in Example 15.

Example 15:

Example15

Fundamental Types of C#

One important thing you must understand about data types in C# is that it divides these data types into two fundamental categories – value types and reference types. Most of the basic data types in C# (for example int, char) are value types. Structures are also value types. Reference types include classes, interfaces, arrays and strings. The basic idea is simple, a value type represents the actual data (stored on the stack), whereas a reference type represents a pointer or reference to the data (stored on the heap). C# determines which types will be values and which ones will be represented as references.

The basic difference between value and reference types is in the way they are stored in the memory. Value types just hold a value in the memory. These types are stored on the stack. Value type is the way C and C++ works when passing a variable to a function, without any specific modifiers. Primitive data types, enums, structs and even objects would fall under this category
for C++ but in C# only primitive data types, enums and structs are treated as Value types.

As for reference types, the memory location of a reference type just contains the address of the object on the heap. If a reference type is null it means that no object has been referenced.

Let us consider the following example.

Example 11:

using System;
class Test
{
   static void Main()
   {
      int value = 10;
      funcTest(value);
      Console.WriteLine(value);
   }

   static void funcTest(int value)
   {
      value = 200;
   }
}

The output of the program would be 10 and not 200 as the value of the variable (value) being changed in the function (funcTest()) is not reflected back in the Main() function. This happens because int is a value type and when passed to the function funcTest() a copy of the value of the variable is passed.

Now consider Example 12.

Example 12:

using System;
class TestClass
{
   public int value;
}
class TestRef
{
   static void Main()
   {
      TestClass x = new TestClass();
      x.value = 10;
      funcTest(x);
      Console.WriteLine(x.value);
   }
   static void funcTest(TestClass x)
   {
      x.value = 200;
   }
}

The output of the program now will be 200. Why did that happen? Simple, the parameter passed to the function this time was an object. And object belongs to the reference type, so when the object was passed the reference (also known as address) to the object was passed and the changes made inside the function were reflected back to the Main() function.

In below Table we have summarized the common characteristics of value and reference types.

Value Reference
Variable Holds Actual Value Reference
Allocated Inline (Stack) Heap
Default Value Zeroed Null
= means Copy Value Copy Reference

As the table depicts:

  • Variables of value type hold the actual value while the reference types hold the address (a reference) of the object.
  • Value types are allocated inline while reference type on the heap.
  • As mentioned in a previously, C# allocates a default value for the variables. The default value for a Value is zeroed while a Reference holds a null reference.
  • Performing the “=” operation on value types copies the value to the destination variable while performing the same operation on reference types copies the reference (also known as address) of the object to the destination.

Boxing and Unboxing

Boxing in simple terms is nothing but conversion of a value type into a reference type. Similarly, unboxing is all about converting a reference type into a value type. This is a very powerful feature of C#. With boxing you can manipulate complex reference types as you would manipulate simple value types. This plays an important role in implementing polymorphism, which we shall discuss in a later post in detail.

To understand boxing ad unboxing clearly, let us consider the program in Example 13:

Example 13:

Example13

In Example 13 we have defined a class, which has two methods. The first method, iTakeObjs() takes in an object as a parameter. The second method iSpitObjs() returns an object, and it takes no parameters. In the implementation part of the code we have declared a variable called v, which is of type int and hence a value type. We assign 5 to v. We also create a new object up of the class BoxMe.

The next two lines are of importance to us. In the line commented BookMark1 we have called the iTakeObjs() method and passed v as the parameter. Recall that iTakeObjs() takes in an Object as parameter. An object is of reference type and we have passed v (a value type) as the parameter. Generally you would think that this would generate an error. However, it does not! The value type v gets implicitly converted into a reference type. This process of converting a value type to a reference type (either explicitly or implicitly, as in this case) is known as Boxing.

Now in the next line marked BookMark2 we have created a new variable of type int called unBox. We have then equated this variable to the iSpitObjs() method. Recall that iSpitObjs() takes in no parameters but returns an object. But we have equated it to a variable of type int, which is of value type. For this reason we have to explicitly cast the object to an int (the type conversion is done by enclosing the desired data type in parenthesis). This process of converting a reference type to a value type is known as Unboxing.

However note that here Unboxing required an explicit cast. The runtime performs a check to make sure that the specified value type matches the type contained in the reference type. If the check fails, an exception is thrown, which if not taken care of will terminate the application. We shall learn how to trap exceptions in a later post.

General C# Programming Constructs

In this post we will look at a few commonly used constructs in C#.

1.   Declaring Variables in C#

Variables in C# are declared in the following way:

AccessModifier DataType VariableName;

The access modifier could be public, protected, private or internal. As you know access modifiers define the level of access that certain blocks of code has to class members like its methods and properties. This access level for each modifier is described below:

Access Modifier Description
public Makes a member accessible from anywhere.
protected Makes a member accessible within the class and all classes derived from it only.
private Makes a member accessible only within a class.

As far as the internal modifier is concerned we shall be discussing it in a later post.

The DataType could be any of the valid variable types in C#. A few of the valid intrinsic C# data types are listed below:

C# Data Type Description
int Declares a variable which stores Integer values. Takes up 4 bytes of memory.
string Declares a variable which stores string values.
float Declares a variable which stores integer values with decimals.

 The data type could also be an array definition or a custom data type like enumerators or maybe even a class name for creating an object. We shall discuss all of these in later posts.

Then follows the variable name, which should be a valid C# variable name. The rules for naming variables in C# are just the same as in C.

In almost all programming languages, keywords are not allowed to be used as identifiers. However, C# has a work-around for this issue. You can use variables which clash with keywords by prefixing the identifier with an @ symbol. The @ is not considered as a part of the identifier however.

Consider the Example 2.

Example 2:

using System;
class Test
{
   static void Main()
   {
      int @int;
      @int = 5;
      Console.WriteLine(@int);
   }
}

Note that in Example 2 we have declared a variable of the type int, and the variable name is also int. We have just pre-fixed the variable name with an @ symbol.

Another new feature related to variables in C# is that they are automatically assigned a default value upon creation. Consider the following example 3.

Example 3:

using System;
class Test
{
   static void Main()
   {
      int[] MyArr = new int[3];
      Console.WriteLine(100 * MyArr[1]);
   }
}

The output of the program will be:

0

In Example 3 we have declared an array of integers called MyArr and no values have been assigned to the array elements. Yet the program does not generate an error when we use the unassigned array element (in the last statement). The compilation and execution takes place smoothly. The reason is that C# assigns a default value to the array elements that are declared. The default value for the type int is zero. This is why the output of above example is 0 (as 100 * 0= 0).

Below Table lists out the default values of common data types.

Type Default Value
Numeric (int, float, short, …) 0
Bool False
Char ‘’
Enum 0
Reference null

 However, remember, this type of default assignment on unassigned elements occurs only for static fields, class instance fields and array elements. For all other variables, the compiler will throw an error. Hence it is considered a good programming practice to assign a value to a variable before using it.

2.   Basic Input Output in C#

Basic input and output operations are performed in C# using the methods of the Console class in the System namespace.

The two widely used methods are

  • WriteLine()
  • ReadLine()

We have already used Console.WriteLine in previous posts. However Console.WriteLine is even more powerful. It can be used to format text before displaying it. It takes up to four additional parameters, which are known as the format string specifiers. The format string specifiers specify how data will be displayed. It can also serve as placeholders, which determine where the values of the specified variables will be displayed in the string.

Consider Example 4, which is a slight variant of Example 3.

Example 4:

using System;
class TestDefaultValues
{
   static void Main()
   {
      int number, result;
      number = 5;
      result = 100 * number;
      Console.WriteLine(“Result is {0} when 100 is multiplied by number”, result);
   }
}

“{0}” acts as a placeholder, which determines where the value of the specified variable (result) will be displayed.

The output of Example 4 will be:

Result is 500 when 100 is multiplied by number

To get input from the user, Console.ReadLine is used. The ReadLine() method reads all characters up to a carriage return. The input is returned as string.

Consider Example 5.

Example 5:

using System;
class InputString
{
   static void Main()
   {
      string input;
      input = Console.ReadLine();
      Console.WriteLine(“{0}”, input);
   }
}

The program will accept a line from the user and echo it back as the output.

3.   Selection Statements in C#

The selection statements are used to perform operations based on the value of an expression. Checking for conditions in C# is the same as in C. We use the if construct for performing conditional branching. The syntax for the if construct is as follows:

if (expression)
{
   // Statements if expression evaluates to True
}
else
{
   // Statements if expression evaluates to False
}

As you can see it is very similar to the C constructs. However, one major difference is that in C# the expression should always evaluate to an expression of Boolean type. This can be understood better with the help of the following example.

Example 6:

int number = 1;
if (number)
   System.Console.WriteLine(“The value is True”);
if (number == 1)
   System.Console.WriteLine(“The value is True”);

When the first if statement is encountered by the compiler it will generate the following error:

Error CS0029: Cannot implicitly convert type ‘int’ to ‘bool’

The error pops up as the expression “number” will not evaluate to a boolean value. While the second if statement will work just fine, as the expression will either result in a True or False. This is a major difference among other programming languages and shows the power of C#’s type safety features!

Next is the switch statement. The switch statement is very similar to the one we used in C, except that in C# it is mandatory to specify a break statement for each and every case block, without which the compiler will generate an error.

The syntax for a switch construct is as follows:

switch (variable)
{
   case value:
      // Statements
   case value:
      // Statements
   default:
      // Statements
}

The switch construct can be used in place of multiple if statements. Example 7 illustrates an example of how a switch statement can be used.

Example 7:

switch (Choice)
{
   case 1:
      Console.WriteLine(“You Choose One”);
      break;
   case 2:
      Console.WriteLine(“You Choose Two”);
      break;
   default:
      Console.WriteLine(“This is the Default Option”);
      break;
}

As it is clear from Example 7, the break statement after each case is not optional as in C/C++. It needs to be specified if the program is to be compiled. No fall troughs are allowed.

One more enhancement in the switch statement in C# over the switch statement of C/C++ is that it allows the switch construct to be used along with strings.

4.   Iteration Constructs in C#

Iteration or looping statements are used to perform a certain set of instructions a certain number of times or while a specific condition is true.

C# provides us with the following types of iteration constructs,

  • The while loop
  • The do loop
  • The for loop
  • The foreach loop

Except for the foreach loop all others are very similar to the ones in C. We shall look at each and every one of them in detail.

  • The while loop

The while loop iterates through the specified statements till the condition specified is true. However, unlike the while loop in C, the C# while loop requires a boolean condition just like the C# if construct.

The syntax for a C# while loop is as shown below:

while (condition)
{
   // Statements
}

The break statement can be specified in the statements to break out of the loop at any time. The continue statement can be specified to skip the current iteration and begin with the next iteration.

  • The do loop

A do loop is very similar to a while loop except that in a while loop the condition is first evaluated and then the execution takes place, whereas, in a do loop the condition is evaluated at the end of the loop. In a do loop the statements in the body of the loop get executed at least once before the condition is checked.

The syntax for a C# do loop is as follows

do
{
   // Statements
} while (condition)

The break and continue keywords can be used even in the do loop.

  • The for loop

The for loop, as in C, is a little different from the other loops. The loop variables maybe declared as part of the for statement.

The syntax for a for loop in C# is as given below:

for (initialization; condition; increment/decrement)
{
   // Statements
}
  • The foreach loop

The foreach loop is new to the C/C++ programmer but instantly familiar to the Visual Basic programmer as the concept has been borrowed into C# from Visual Basic. The foreach loop is usually used to iterate through a collection or an array.

The syntax for a foreach construct is as follows:

foreach (Type Identifier in expression)
{
   // Statements
}

Consider Example 8:

Example 8:

using System;
public class ForEachEx
{
   static void Main(String[] args)
   {
      foreach(String str in args)
      {
         Console.WriteLine(str);
      }
   }
}

If we compile and run the program by passing the three names as the command line parameters as shown below:

ForEachEx Scooby Scrappy Shaggy

The output will be:

Scooby

Scrappy

Shaggy

The foreach loop simply iterates through the array args and puts the values contained within it one at a time into the variable str, which is then displayed on the console.

5.   Constructors in C#

As we already know, constructors are special methods. As in case of C++, the constructor in C# also has the same name as the class. Example 9 below provides the syntax for defining a constructor for a class.

Example 9:

…
class MyClass
{
   public MyClass()
   {
      // MyClass Constructor
   }
}
…

6.   Destructors in C#

Destructors in C# are written in the same way as constructors are written. The destructors in C# have the same name as the class except that there is a ~ (tilde) symbol prefixed to it.

Building on Example 9 is Example 10,

Example 10:

…
class MyClass
{
   public MyClass()
   {
      // MyClass Constructor
   }

   public ~MyClass()
   {
      // MyClass Destructor
   }
}
…

The destructors in C#, though, are defined just as in C++; they tend to behave differently as the destructor is called by the Garbage Collector. The Garbage Collector is a service of the .net runtime, the CLR. The exact working of the Garbage Collector will be discussed at a later post.

C# Program Flow

To understand the flow of a C# program, let us begin by analyzing a very simple program in C#. Example 1 shows a program written in C#, which simply displays a message on the user’s screen.

Example 1:

001:   /* This is a simple program in C# */

002:

003:   using System;

004:   class First

005:   {

006:      public static void Main()

007:      {

008:         Console.WriteLine(“My simple program in C#”);

009:      }

010;   }

Line 001: This is a comment. Comments can be included in any part of a C# program. Here we have used a standard C/C++ style comment. The comment begins with “/*” and ends with “*/”. The comment can span multiple lines.

Line 003: This line, using System, is quite similar to the #include statement used in C/C++. The #include statement was used to include another header (source) file, so as to make the functions, present within that header file, a part of the current program. Similarly the keyword using imports the System class file and makes the methods present within it as a part of the program. But System here is known as a namespace and not as a header file. We shall discuss namespaces in a later post and see how they are different from C/C++ header files. For now, just think of namespaces as a collection of classes. The System namespace contains the classes that most applications use for interacting with the operating system. The classes that are used more often are the ones required for basic Input/Output. Note that there is a semicolon at the end of this line. All lines of code in C# must end with a semicolon, just like in C/C++. As you can see for yourself, C# has strong roots in C and C++.

Line 004: This line defines a class.

Line 006: Each class has one static void Main() function. This function is the entry point of a C# program. This means that the Main() function is the first function that is called when program execution begins. It is declared as public to make it accessible from just about anywhere in the program. The keyword public can be ignored, as by default, just as in C++, in C# also the members of a class are public. The Main() function is declared as a static member (static members will be discussed in detail later). Since in our program the Main() does not return any value its return type is declared as void. Do keep in mind the case of the keywords, all keywords on this line of code are in lower case except in case of the Main() function M is in upper case.

Line 007: Next we open the scope of the method (or function) using curly braces.

Line 008: Within the Main() function we call the WriteLine method of the Console class and pass the text “My simple program in C#” as its parameter. The WriteLine function displays text on the console or the DOS window. Note that the WriteLine method is a part of the Console class, which in turn is a part of the System namespace. If we had not specified the using System clause in Line 003, we would have had to write this line (Line 008) as:

System.Console.WriteLine(“My simple program in C#");

Using a fully qualified name to refer objects can be error prone. To ease this burden, C# provides us with the using directive, which we specified at Line 003. Also remember that you can put more than one using directive, but they all must be specified at the beginning of the program.

Line 009: The Main() function is terminated using the closing braces.

When the program is executed it will just display the message “My simple program in C#”. Though it may seem like it has not accomplished much, do not think likewise. You have just understood the basic flow of program execution in C#!

A point to note is that as mentioned earlier, C# is case sensitive! For example, the “using” is not the same as “Using”!

Introduction to C# Basics

Microsoft .net was formerly known as Next Generation Windows Services (NGWS for short). It is a completely new platform for developing the next generation of windows/web applications. These applications would transcend device boundaries and fully harness the power of the Internet. However, this new platform required a language which could take its full advantage; this is one of the factors that led to the development of C#. C# has evolved from C/C++. Hence, it retains its family name. The # (hash symbol) in musical notations is used to refer to a sharp note and is called “Sharp”, hence the name is pronounced as C Sharp.

The .net platform supports more than 20 different languages and the list is growing every day. The C# compiler is considered to be the most efficient compiler in the .net family and a major part of the .net base classes libraries (which constitute a major part of .net) itself are written in C#.

Moreover, C# could be considered as a modern replacement for C/C++ languages. It gives access to many of the facilities previously available only in C++, while retaining some of the simplicity of Visual Basic. Though other languages have been plugged into the .net platform, C# was developed specifically for the new platform. All these reasons put together make C# the preferred choice of language for the .net platform.

It is important to look at C# not just as a programming language but as an integral part of the .net platform. The .net platform revolutionizes facilities available for Windows programming. It provides benefits like the automatic garbage collector for automatically cleaning up resources occupied by dead objects, and enhanced libraries that cover areas ranging from Windows GUI support to data access to generating ASP.net pages.

Another important feature of C# is that it is a real object-oriented programming language. This may not sound very exciting since we do have powerful programming languages like C++, and C# has its roots in C++. C++ though a well-designed object oriented language never actually enabled code re-use. Just to cite an example, in C++ you required access to the header files, where the original source code resided, in order to be able to inherit the classes contained within them. Moreover, C/C++ were full of pitfalls and even experienced programmers could blunder easily. As an example, just a missing break statement in a select case block could cause disaster. C# addresses all these problems and makes it a safer realm for both, the experienced and the inexperienced programmers.

The key point of C# however is that it enhances developer productivity and increases safety, by enforcing strict type checking. It features a garbage collector, which relieves the programmer of the burden of manual memory management. C# offers extensive interoperability. The managed environment is appropriate for most enterprise applications. Some applications do require “native” code, either for performance reasons or to interoperate with existing application programming interfaces (APIs). In such situations developers use C++ even when they would prefer to use a more productive and easier language. For example, the Windows API is written in C/C++. This forces the developers to use Visual C++ for system-level programming, even though they would prefer to use Visual Basic. C# addresses these problems by providing the simplicity and the productivity of Visual Basic while providing native support for the Component Object Model (COM) and Windows-based APIs. C# also allows restricted use of native pointers.

In the later posts we will be looking at the basic programming constructs of C# and the fundamental data types in C# namely value and reference types. We will also be looking at the concept of boxing and unboxing. And finally we will see how to write and compile a simple C# program.