TUTORIELS 
Passer de C++ à C#
Présentation de quelques-unes des différences notables entre les deux langages, pour aider le développeur C++ à la transition.  (4 novembre 2002 )
 

Introduction
Digne successeur (selon Microsoft) des langages C/C++, C# est certes proche de ses prédécesseurs, mais présente des différences notables qui peuvent représenter des pièges pour le développeur se jettant directement dans ce langage. En effet, si la ressemblance entre C++ et C# est frappante et permet de faciliter la transition d'un langage à l'autre, un programmeur C++ ne peut pas sauter de l'un à l'autre en ne connaissant que les syntaxes respectives: bien que syntaxiquement similaires, ces deux langages présentent de grandes différences au niveau de leur conception même, suffisamment pour rendre la transition plus difficile qu'elle ne paraîtrait au premier abord.

L'exemple sempiternel présente de première variations:

(fichier helloworld.c)
#include <iostream>
int main() {
  std::cout << "Hello, world!\n";
  return 0;

  }

(fichier helloworld.cs)
using System;
class HelloWorld {
  static void Main() {
    Console.WriteLine("Hello world!");
    }
  }

Comme le noterons les programmeurs C/C++, il manque certains éléments:
- Le programme n'utilise pas de méthode globale pour Main. Les méthodes et variables ne sont pas supportées au niveau global, mais sont contenus dans des déclarations de type (classes...).
- Le programme n'utilise aucun opérateur :: ou -> . :: n'est pas un opérateur en C#, et l'opérateur << n'est utilisé que rarement dans les programes. L'opérateur . est utilisé pour les noms composés, comme Console.WriteLine.
- Le programme ne contient pas de "forward declaration". Elles sont inutiles, étant donné que l'ordre de déclaration n'est pas pris en compte.
- Le programme n'utilise pas #include pour l'importation. Les dépendances entre programmes sont gérées de manière symbolique plutôt que textuelle. Cette approche élimine les barrières entre les programmes écrits dans différents langages. Par exemple, la classe Console pourrait être écrite dans un autre langage.
- pas de ; après la déclaration de classe.

Ainsi, vous pouvez écrire du code parfaitement légal en C++, il ne compilerait pas pour autant en C#. Pire, il pourrait ne pas se comporter de la manière prévue. Nous allons aborder dans cet article quelques points spécifiques à C# qui le différencient de C++.

Typage
C# fait une différence entre les types de valeur (value) et les types de référence (reference). Les types simples (in, long, double, ...) et les structs sont des types de valeur, tandis que toutes les classes sont des types de référence, tout comme les objets, interfaces, tableaux et chaînes. L'occurence d'un type value représente la donnée réelle (stockée dans la pile), là où celle d'un type référence représente un pointeur ou une référence aux données (enregistrées sur le segment de mémoire). Pour résumer, un type valeur en C# correspond à une variable en C++, et un type référence à un pointeur.
Là où un programmeur C++ doit faire attention, c'est que C# détermine lui-même les types qui seront représentés comme valeurs et ceux qui seront représentés comme références...

Structures
Il y a des différences majeures entre les structs de chaque langage. En C++, une struct est une forme de classe, sauf que les héritages et accès sont par défaut publics plutôt que privés. En C#, les structs sont bien différentes des classes: elles sont conçues pour encapsuler de petits objets, et sont de type valeur (pas référence), donc sont passées par valeur. Elles ont des limitations qui ne s'appliquent pas aux classes, n'ont pas de construction par défaut (sans paramètre), et n'ont pas de destructeur.
Le bénéfice est que les structs de C# sont plus efficaces que les classes pour la création d'objets légers.

Tout est objet
En C#, tout dérive de la classe System.Object, en définitive: classes, types de valeur... De fait, vous pouvez assigner une valeur de n'importe quel type à une occurence d'Object. En C++, les héritages multiples sont permis dans le modèle objet, ce qui n'est pas le cas en C#: il ne permet qu'un héritage d'une classe de base, bien qu'une classe C# puisse implémenter de multiples interfaces.
En C#, il n'y a qu'un seul symbole pour faire référence à une valeur ou un attribut: le point. Que vous fassiez appel un attribut, une classe ou un espace de nom, vous utilisez le point et C# se charge de déterminer comment interpréter la réference.
La classe Objet offre quelques méthodes utiles.

Paramètres
En C# comme en C++, une méthode ne peut renvoyer qu'une seule valeur. En C++, on peut dépasser cette limitation en utilisant des pointeurs ou références dans les paramètres. En C#, il faut passer par les affectations définies/assurées (definite assignments, un "héritage" de Java), ce qui signifie que les variables locales doivent être affectées avant d'appeller la méthode. Pour éviter cela, C# dispose du mot-clé out, qui indique que l'on peut passer une variable non initialisée, et elle sera passée par référence.

C++: public void GetStats(ref int age, ref int ID, ref int yearsServed)
C# : public void GetStats(out int age, out int ID, out int yearsServed)

New
Le mot-clé new permet en C++ d'instancier un objet du "tas" (heap). En C#, avec les types référence, le mot-clé new fait de même, mais avec les types valeur comme les structs, l'objet est créé sur la pile (stack) et un constructeur est appellé.

Propriétés
En C#, les propriétés sont les éléments premiers d'une classe. Pour le client, elles ressemblent à des variables, mais pour l'implémenteur de classes, elles ressemblent à une méthode. Cela permet une encapsulation totale tout en donnant au client un accès à ses membres.

public int Age
  {
  get
    {
    return age;
    }
  set
    {
    age = value;
    }
  }

Fred.Age = 17;

Tableaux
C# dispose d'une classe de gestion de tableaux mieux faite que les tableaux C/C++. Par exemple, il est impossible de sortir des limites d'un tableau C#. Il y a trois sortes de tableaux C#: unidimensionnel, multi-dimensionnel et les tableaux de tableaux (jagged arrays).

int[] tableau = new int[5];
ou
int[] tableau = { 2, 4, 6, 8, 10 };

int[,] tableauMulti = new int[lignes, colonnes];
ou
int[,] tableauMulti =
  {
  {0,1,2}, {3,4,5}, {6,7,8}, {9,10,11}
  };

int[][] jaggedArray = new int[4][];
puis
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[2];
jaggedArray[2] = new int[3];
jaggedArray[3] = new int[5];

Ce ne sont là que quelques exemples parmi de nombreux autres. Notre but n'est évidemment pas de dire que le programmeur C++ serait perdu dans un environnement C#, bien au contraire, mais qu'il lui faudra s'adapter à l'environnement (en particulier l'architecture .NET) et à quantité de petites variations dans la syntaxe, comme nous avons commencé à le montrer ici.

 
[ Xavier Borderie,JDNet
 
Accueil | Haut de page