The C# language is based on the syntax and semantics of C++, allowing Programmer C to benefit from .NET and Common Language Runtime. While the transition from C++ to C# may seem easy, there are a number of elements that have changed that we are going to study such as the new operator, structures, constructors, destructors.
The C# language looks very much like C++. You may be writing code that is perfectly correct in C++, but does not compile in C# or at worst does not perform at runtime as expected. Most of the syntactical differences between C++ and C# are trivial (no semicolon after declaring a class, Main now has a capital letter) and are detected by the compiler.
The main differences between C++ and C#
- Inheritance: A class can inherit the implementation of only one base class. A class or an interface can implement multiple interfaces.
- Arrays: The declaration of an array in C# is different from that in C++. The square brackets [] should appear after the table type in C#.
- Bool type: there is no conversion between the bool type and other types (especially int).
- Long type: in C#, the long data type is on 64 bits whereas it is on 32 bits in C++.
- Struct type: in C#, classes and structures are semantically different. A structure is a type of value whereas a class is a type of reference.
- Switch statement: compared to C++, the C# does not allow the automatic switch to each condition of a switch clause.
- Delegate type: delegates look like function pointers, but they are secure and strongly typed.
- Call a member function of an overloaded class from a derived class.
- Use the new keyword to explicitly hide an inherited function.
- Overloading a method requires the use of the override keyword.
- Preprocessing directives are used for conditional compilation. There is no includes file in C#.
- Exception handling: the use of the finally clause.
- C# operators: The C# has additional operators such as is and typeof as well as different functionalities of some logical operators.
- The use of the keyword extern.
- Use of the static keyword.
- An alternative solution to the C++ initialization list in building a base class.
- The general structure of a C# program: namespaces, classes, structures, delegates, enumerations.
- The declaration of the Main method differs from that in C++, but also the manipulation of arguments passed on the command line.
- The parameters of the methods: the C# supports the reserved words ref and out, which are used in place of pointers for the parameter passing by reference.
- Pointers are allowed in C#, but only in a mode called “unsafe”.
- Operator overload is different in C#.
- C# strings are different from C++ strings.
- The keyword foreach allows you to browse tables and collections.
- There are no global methods or variables in C#: methods and variables must be contained in the scope of a declaration (such as a class or structure).
- There are no header files or inclusion directives in C#: the using keyword is used to reference namespaces.
- Local variables in C# can not be used without initialization.
- Destructors: in C#, it is not possible to control the call of destroyers, because these are called automatically by the garbage collector.
- Constructors: Compared to C++, if you do not supply a constructor, a default constructor is automatically generated. It will initialize all fields with their default value.
- The C# does not support “bit” type fields.
- Input / output and data formatting services are based on the RunTime of the .NET Framework.
- In C#, the parameters of the methods can not have a default value. You have to overload the methods to get this result.
Types of value and reference
The C# distinguishes the types of value from the reference types. Simple types (int, long, double …) and structures are value types while classes are reference types just like objects. The value types represent the actual data stored on the stack and are passed to methods by value (a copy is made). Reference types contain the address of an object stored on the heap and are passed as a parameter by reference.
Structures
The structures are different in C#. In C++, structures are exactly like a class, except that inheritance and default access is public and not private. In C#, the structures are designed to encapsulate small objects and are of value type (thus passed by value). They are limited in that they can not derive from any class except System.ValueType and they can not define a default constructor (without parameters). In return, the use of a structure is preferable to that of a class for very small objects.
Everything derives from the Object class
In C# finally everything derives from the class Object as well the classes you create as the types of value (int, struct …). The Object class has useful methods like the ToString method. Consider an example of using the ToString method and the System.Console.WriteLine method (cost equivalent in C++). Consider a myEmployee object as an instance of the Employee object and a myCounter object as an instance of the Counter object. If we write the following code:
1 2 3 |
Console.WriteLine("The employee: {0}, the counter value: {1}", myEmployee, myCounter); |
The WriteLine method will call the Object.ToString virtual method of each of these objects and substitute the strings that the parameters will return. If the Employee class does not override the ToString method, the default implementation will be called, which returns the name of the class. The Counter class will override the ToString method to return an integer resulting in the following result at runtime:
The employee: Employee, the counter value: 12
What happens if you pass an integer to the WriteLine method? It is not possible to call the ToString method on an integer, but the compiler will implicitly transform the integer into an instance of the Object whose value will be that of the integer. This transformation is called boxing.
You will find attached the complete example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
public class Employee { } public class Counter { private int theVal; public Counter(int theVal) { this.theVal = theVal; } public override string ToString() { Console.WriteLine("Calling Counter.ToString()"); return theVal.ToString(); } } class Program { public static void Main() { Program p = new Program(); p.Run(); } public void Run() { Employee myEmployee = new Employee(); Counter myCounter = new Counter(12); Console.WriteLine("The employee: {0}, the counter value: {1}", myEmployee, myCounter); int myInt = 5; Console.WriteLine("Here are two integers: {0} and {1}", 17, myInt); } } |
Parameter management of function prototypes
In C# as in C++ a method can have only one value in return. To overcome this limitation in C++, the parameters are passed by references or via pointers. The called method changes the value of the parameters and makes them accessible to the calling method. In C# when you pass a reference to a method you have access to the original object, as in C++ with the passage by reference or pointers. On the other hand, it does not work with value types. If you want to pass a type of value by reference then, it must be preceded by the keyword ref.
1 2 3 |
public void GetStats(ref int age,ref int ID,ref int yearsServed) |
It is important to specify that the reserved word ref must be used both in the declaration of the method and in the calling method.
1 2 3 |
WHOAMI.GetStats(ref age, ref ID,ref yearsServed); |
You can now declare the age, ID, yearsServed fields in the calling method and pass them to the GetStats method and retrieve the modified values back.
In C# it is necessary to initialize the variables before passing them to the method GetStats (definite assignment). It is possible to avoid this initialization by using the out keyword. Using the out keyword in C#, you indicate that the variable is not initialized and passed by reference.
1 2 3 |
WHOAMI.GetStats(out age, out ID,out yearsServed); |
As when using the ref keyword, the out keyword should be used in both the method declaration and the calling method.
1 2 3 |
WHOAMI.GetStats(out age,out ID,out yearsServed); |
“new” keyword
In C++, the New keyword instantiates an object on the job. The C# language does the same with the reference types. For value types such as structures, the object is created on the stack and a constructor is called.
You can also create a structure on the stack without using the New keyword, but be careful because new initializes the object. This means that all structure values must be initialized by hand (before switching to a method).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public struct Point { public Point(int x, int y) { this.x = x; this.y = y; } public int x; public int y; } public class Program { public static void Main() { Program p = new Program(); p.Run(); } public void Run() { Point p1 = new Point(5, 12); SomeMethod(p1); Point p2; p2.x = 1; p2.y = 2; SomeMethod(p2); } private void SomeMethod(Point p) { Console.WriteLine("Point at {0} x {1}", p.x, p.y); } } |
Properties
In C++, programmers try to keep private member variables. This is the very principle of encapsulation that allows to modify the implementation of a class without changing the interface. Concretely, the C++ developer will create accessors to modify the values of private member variables.
In C#, properties are the first members of a class. For a client, a property looks like a member variable, but for the class developer it’s more like a method. Properties promote encapsulation and provide the customer with easier access to class members.
For example, consider an Employee class with an Age property that allows a customer to value or retrieve an employee’s age.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public int Age { get { return age; } set { age = value; } } |
The value keyword is implicitly defined through the property. If you write
1 2 3 |
WHOAMI.Age = 17; |
the compiler will set value to 17.
It is possible to implement a read-only property, just do not implement a set accessor.
1 2 3 4 5 6 7 8 9 |
public int YearsServed { get { return yearsServed; } } |
Arrays
The C# provides a more comprehensive table management class than the traditional C / C++ array. For example, you can not write outside the boundaries of an array. In addition C # offers an ArrayList class whose size can grow dynamically according to the needs of the program.
There are three types of arrays: one-dimensional, multidimensional, and arrays of arrays (jagged array).
You can create a one-dimensional array as follows:
1 2 3 |
int[] myIntArray = new int[5]; |
or initialize it as follows:
1 2 3 |
int[] myIntArray = { 2, 4, 6, 8, 10 }; |
You can create a two-dimensional array as follows:
1 2 3 |
int[,] myRectangularArray = new int[rows, columns]; |
or initialize it as follows:
1 2 3 |
int[,] myRectangularArray = { {0,1,2}, {3,4,5}, {6,7,8}, {9,10,11} }; |
As jagged array are arrays of arrays it is necessary to provide only one dimension.
1 2 3 |
int[][] myJaggedArray = new int[4][]; |
and then create each of the internal arrays:
1 2 3 4 5 6 |
myJaggedArray[0] = new int[5]; myJaggedArray[1] = new int[2]; myJaggedArray[2] = new int[3]; myJaggedArray[3] = new int[5]; |
Because tables derive from the System.Array object, they have many methods, including Sort and Reverse.
Conclusion
Through this article we have discussed the main differences between C# and C++. It turns out that the transition to C# for an experienced C++ developer should be done without too much difficulty the syntax approaching much between these two languages. However, be careful not to fall into the easy way and program in C# as you would in C++ at the risk of having unexpected behavior.
Note: It is quite possible that there are errors in the document. If you find some, or would like a little more explanation on some points, please send me a private message via the forum to update all of this document. Thanks in advance.