The .NET Platform was created by Microsoft and initially released in 2002. Supported by Microsoft, it is only available for Windows operating systems, but Unix-like environments can use an open source alternative called Mono. When Microsoft released the .NET Platform, they created a general guideline for the platform so anyone could implement it. In 2005, the ECMA approved the Common Language Infrastructure (CLI) and C# programming language specification, so from that point, anyone could follow the standard. The Mono project implements this standard and offers an alternative for non-Windows users.
In 2015 Microsoft started to open-source all the .NET framework source code, which also helped the Mono project keep up with the new features of the platform. The .NET platform supports many programming languages, like VB.NET, J#, F# and C#, but C# is still the most widely adopted. The current stable version of the .NET platform is 4.6.1 and C# language is 6.
In the image below you can see how the different features of the .NET platform were added on each version (image source: Wikipedia). The first part of the article covers features that were already introduced in .NET Framework 2.0.
The next four topics (CLI, Metadata, CTS and VES) are all part of the Common Language Runtime, while BCL is marked as Framework Class Library on this diagram.
What is CLI?
CLI stands for Common Language Infrastructure. This is a standard approved by ECMA International and details how applications written in different high level programming languages (C#, VB.NET or J#) should generate executables, and what metadata needs to be added to the libraries so these can run on different CLI-compliant platforms. The CLI describes the CTS (Common Type System), CLS (Common Language Specification), and VES (Virtual Execution System), plus Metadata.
What is Metadata?
The metadata contains programming language-agnostic (different for each programming language) information which helps the VES identify the language and the execution flow for the program. It also maps the types used in the programming language to the ones defined in the CTS. Besides these, the metadata contains information related to the version of .NET Framework the source code was built with, such as the name, author and version of the assemblies.
What is CTS (Common Type System)?
The CTS defines the data types in the programming language and specifies how these should be used. The CTS ensures that using the common types the software can be executed and will run the same way on multiple platforms. The CTS also defines the rules and guidelines for programming languages on how to treat internal operations of types. Common Types in.NET are all the types that are written with capital letters in the source code, such as String, Int, Long, and Char. Each programming language usually has an internal type for each common type. For example, the C# has string type for storing character arrays, but CTS defines the String type (please note the difference between the first letters; the CTS type has capital S). You can read more about types below.
What is VES?
The Virtual Execution Environment is executing the code which was compiled to the common language. The VES can be available for every platform. Microsoft offers its own VES for Windows, Windows Server, Windows Phone, but if you are using a Unix based system then you can use Mono’s VES for code execution.
What is the BCL (Base Class Library)?
The Base Class Library (a.k.a Framework Class Library) is a set of classes and namespaces which offer the minimum support for writing high level applications using the .NET platform. The BLC includes the System, System.Collections, System.Collections.Generic, System.IO, System.Text namespaces. These namespaces contain classes like List, ArrayList, FileReader, FileWriter, Hashtable, Dictionary and so on, which have a support role when building a business application, and also helps speed up the development process. The BCL was released with the first version of .NET, and since the .NET Framework 2.0, it did not change at all. It was only optimized and ported to other platforms and new programming languages, like J#.
Programming with C#
C# is one of the most widely-used programming languages from the .NET platform. When appeared, it had a lot of elements from the Java programming language. This means that C# is C syntax based; it is an Object Oriented Programming language and does not support multiple inheritance. The source code files of C# have the .cs extension. C# is a statically typed programming language, but in .NET 4.0, the dynamic keyword has been added to the language which enables us to do some nice tricks, BUT please keep in mind that even if you are using a dynamic construct, the language is still statically typed, and behind the scenes there are Anonymous types created for the dynamically defined content too.
Before you can start programming in C# you will need to make sure that you have the .NET Framework or Mono installed on your machine, depending on your OS. I am on MacOS X, so I installed the Mono package, which can be downloaded from the Mono website. Once the package is installed I need to make sure that I have the compiler available. On Windows you can check this if you type in the csc --version in the command line and it should display the version of the C# compiler. The Mono compiler can be accessed using the msc --version.
Below you can see the simplest C# program, which will ask for your name and say hi to you plus it will tell the current time and date:
using System;
using System.Collections;
namespace SayHello {
public class SayHello
{
public static void Main (string[] args){
Console.WriteLine("Hi, I'm Nancy! What is your name?");
String name = Console.ReadLine();
Console.WriteLine("Hi {0}, pleased to meet you. The current time is {1} and the curent date is {2}",
name,
DateTime.Now.ToString("hh:mm:ss"),
DateTime.Today.ToShortDateString());
}
}
}
The program starts with the declaration of the using section, where we define all the necessary namespaces what we want to use in our program. After the using comes our namespace definition using the namespace keyword. The C# language has namespaces similar with the way C++ has. The next line contains the class declaration. The class should be public, because it will contain the Main method. The Main method needs to be a public static void method; it has to be static because we only have one Main method within a C# program.
The Console class provides access to the command line of the operating system. Using this, you can write messages to the console and ask for input from the user. First, I write Hi, I’m Nancy! What is your name? to the console with the WriteLine method, then I read the input from the user, using the ReadLine method.
In the next line, I write to the console the message for our user. In the string, we have numbers added between curly braces, like {0}, {1} and {2}. These are placeholders and will be substituted with the parameters coming after the string, in this case name (the input from the user), DateTime.Now.ToString() with formatting and the DateTime.Today.ToShortDateString(). The format string hh:mm:ss can be used in case of the DateTime type, this will display the time in format of hours, minutes and seconds, separated using a colon (:).
Here is an image of the output of the program:
Types in .NET
In the source code above, I used two data types, DateTime and String. Now I will cover other types. In .NET there is an implicit initialization for each type. Types can be divided into value types and reference types. Value types are int, char, byte, long, decimal, float, double. The string type is a reference type.
In the code below, I cover the int, long and decimal types. The int type is a 4byte (aka 32bits) big number. The long type is a 64bit value. The decimal type is 64bit floating point, with double precision.
public static void Main (string[] args)
{
int number = 13;
long bigNumber = long.Parse(Math.Pow(2, 36).ToString());
Console.WriteLine("Here is a big Number (larger than 2^32): {0}", bigNumber + number);
Console.WriteLine("The same Decimal value is multiplied by PI is: {0}", (decimal)(bigNumber + number) * 3.1415m);
var myPhrase = "The quick brown fox jumped over the lazy dog";
Console.WriteLine("The first occurence of q in the phrase: '{0}' is at index: {1}", myPhrase, myPhrase.IndexOf('q'));
}
In the Main method I declared an int variable (called number) initialized to the value 13. Then a number of type long (bigNumber) is declared, which has a value of 2^36.
After the initialization, I write the numbers into the console. First by writing the sum of bigNumber and number, followed by the product of bigNumber and the value of Pi (3.1415).
Then I declare a string. Please note that I am using the var keyword to declare a variable and I have not specified explicitly that I am declaring a string. The compiler can deduct that based on the value on the right side of the equal sign. The last line of the program displays the index of the first appearance of the q letter in the variable called myPhrase.
The output of the code is:
Custom Types
The first custom type that I present is the Enum type. Enums can be declared by developers. Usually Enums are used when we can distinguish the elements based on a certain value. For this common element, we usually use an enum.
public enum TireType {
WET = 1,
DRY = 2,
INTER = 3
}
We can assign integer values to enum values, and these do not have to be consecutive numbers. The TireType enum has three values, WET, DRY and INTER (which stands for intermediate). You will later how the enum type can be used.
The next custom type is struct. Structs ideally should be used in case we want to create a composition of only value types. An example of a struct is this:
public struct Car {
public TireType tire {get; set;}
public int nrOfLaps {get; set;}
public int fuel {get; set;}
public override string ToString() {
return string.Format("My car has {0} tires, I raced {1} laps and I still have {2} liters of fuel.",
tire, nrOfLaps, fuel);
}
}
I created a struct called Car and it has three properties, tire, nrOfLaps and fuel. Each of the properties has a getter and a setter (in code this is defined using the get and set keywords). Please note that I have defined an override for the ToString() method. The ToString() method is defined on the Object level (base type in .NET), which can be overwritten.
Here is a main method which uses the struct:
public static void Main (string[] args){
var myRaceCar = new Car() {
tire = TireType.DRY,
nrOfLaps = 22,
fuel = 13
};
Console.WriteLine(myRaceCar);
}
Here I create a new instance of the Car struct, I use the inline initialization, I set the tire to the DRY value, the nrOfLasp to 22 and the fuel to 13. In the last line of Main method, I write to the console the myRaceCar object. As you can see I did not invoke any method on myRaceCar, the WriteLine() method will invoke the ToString() method of the object it gets as parameter if that does not have the string type. The output of the program is:
So there – we've covered the basics of the .NET framework and some basic C# features. I showed examples with the struct and enum custom types from C#, and it also shows how to overwrite the ToString() method, as well as how to use types and type conversion in the language.