Alors que je me baladais sur un forum C#, je suis tombé sur une question concernant les mots clés ref et out. J’ai donc décidé de rédiger un petit point technique sur ces deux mots clés …et plus généralement sur les passages par référence et par valeur en C#.
Passage par valeur et référence …
Imaginons le programme suivant :
{
protected static void changeNumero(int numero)
{
numero = 15;
}
static void Main(string[] args)
{
int n = 10;
changeNumero(n);
Console.Write(n);
Console.Read();
}
}
Que va afficher le programme suivant ? 10 ou 15 ?
La réponse est 10. L’explication est simple, nous initialisons une variable n de type int à 10. Toutefois, lorsque nous passons notre variable dans la méthode changeNumero, c’est une copie de n qui est crée.
Ce qu’il faut retenir c’est que les types natifs sont des valueType. Ainsi, lorsque l’on passe une variable de ce type dans une méthode, c’est une copie qui est crée et donc aucune modification n’aura lieu sur la variable crée hors de la méthode.
MSDN propose une page dédié aux Types Valeur. Attention, il existe une exception : la type string est un type référence.
Revenons à notre exemple : Comment peut-on faire en sorte que notre variable soit réellement modifiée dans la méthode changeNumero ? Eh bien c’est ici qu’intervient le mot clé ref qui va permettre le passage dans la méthode non pas d’une copie de la valeur mais d’une référence pointant vers la variable.
{
protected static void changeNumero(ref int numero)
{
numero = 15;
}
static void Main(string[] args)
{
int n = 10;
changeNumero(ref n);
Console.Write(n);
Console.Read();
}
}
Dans cet exemple, la console affiche 15. En effet, dans la méthode Main, on a transmis à la méthode changeNumero une référence vers la variable n. Ainsi, lorsque la variable numero est modifiée, c’est bien la valeur de la variable passée en référence qui est modifiée.
Les types objet, Class, Interface, string,… (Voir la liste des type Référence sur la MSDN) sont quand à eux des types référence.
out ou ref ?
L’autre question que l’on se pose : Quelle est la différence entre le mot clé out et ref ?
Ces deux mots clé permettent de passer dans les méthodes des références. Toutefois, ref doit être utilisé pour une variable déjà initialisé. Quand au mot clé out, il permet à la variable d’être considéré comme variable de sortie. Ainsi, la variable passé en out n’a pas besoin d’être initialisé.
{
protected static void changeNumero(out int numero)
{
numero = 15;
}
static void Main(string[] args)
{
int n;
changeNumero(out n);
Console.Write(n);
Console.Read();
}
}
Ici, la variable est considérée comme variable de sortie. Dans la méthode changeNumero, si la variable est out, aucun test ne peut être effectuée. Ainsi l’exemple suivant génère deux erreurs à a compilation :
- Erreur 1 Utilisation du paramètre out non assigné ‘numero’
Erreur 2 Le paramètre de sortie ‘numero’ doit être assigné avant que le contrôle quitte la méthode actuelle
class Program
{
protected static void changeNumero(out int numero)
{
if(numero < 10)
numero = 15;
}
static void Main(string[] args)
{
int n;
changeNumero(out n);
Console.Write(n);
Console.Read();
}
}
De la même manière, une variable utilisée avec le mot clé ref doit être initialisé.
Ainsi le programme suivant génère une erreur lors de la compilation :
- Erreur 1 Utilisation d’une variable locale non assignée ‘n’
{
protected static void changeNumero(ref int numero)
{
if(numero < 10)
numero = 15;
}
static void Main(string[] args)
{
int n;
changeNumero(ref n);
Console.Write(n);
Console.Read();
}
}

