Nous avons déjà évoqué ce point dans les cours précédents, mais nous allons renforcer notre compréhension grâce au fonctionnement du stockage mémoire.
Ce tutoriel est issu de foxdevelop.com. Veuillez indiquer la source si vous le republiez.
On peut imbriquer d’autres blocs de code au sein du corps d’une méthode.
class Program
{
static void Main()
{
int age = 19;
{
int one = 23;
}
}
}
Langage du code : C# (cs)

Il n’y a pas de limite au nombre de blocs de code. Ils peuvent être disposés à la suite ou imbriqués sur plusieurs niveaux, sans contrainte de profondeur.
class Program
{
static void Main()
{
int age = 19;
{
int one = 23;
{
int two = 45;
{
int three = 56;
}
}
}
}
}Langage du code : C# (cs)

Attention : l’instruction int xxxx = xxx; située au-dessus d’un bloc imbriqué est une instruction parallèle à ce bloc.

Par exemple, int age = 19; et le bloc de code imbriqué qui suit sont deux instructions parallèles. Ne confondez pas cet ensemble avec un corps de méthode.
Cycle de vie
Observons un exemple
static void Main()
{
int a = 10;
{
int b = 20;
}
}Langage du code : C# (cs)
Dans cet exemple, nous avons deux variables locales. La variable externe a appartient à la portée principale de la fonction Main, tandis que b appartient au bloc imbriqué interne.
Suivons l’exécution pas à pas pour voir comment la mémoire de pile est organisée.

Étape 1 : Seule l’instruction int a = 10; s’exécute. La pile alloue une place pour a avec la valeur 10 ;
Étape 2 : On entre dans le bloc interne pour exécuter int b = 20;. La pile ajoute b. Du haut vers le bas de la pile : b, a ;
Étape 3 : Le bloc de code interne a terminé son exécution. b est retiré de la pile, seul a reste présent.
Étape 4 : La méthode Main finit de s’exécuter. a est supprimé de la pile, toutes les variables du programme sont détruites et l’exécution s’arrête.
Synthèse
Une variable déclarée dans un bloc imbriqué voit son cycle de vie commencer à sa déclaration et se terminer à la fin du bloc qui la contient.
Lorsqu’un bloc imbriqué termine son exécution, toutes ses variables locales sont retirées et détruites depuis la pile.
Le corps d’une méthode est lui-même un grand bloc de code.
Portée
Tant que la portée d’une variable existe, il est interdit de déclarer une nouvelle variable locale du même nom, quel que soit le nombre de niveaux d’imbrication.
Voyons un exemple
static void Main()
{
int a = 10;
{
int a = 20;
}
}Langage du code : C# (cs)

Dans cet exemple, la variable a du bloc interne porte le même nom que la variable a externe. Cela provoque une erreur et la compilation échoue.
Explication : La portée de int a = 10; correspond aux accolades qui l’encadrent. Dans cette portée, les doublons de noms de variable sont interdits. Même si int a = 20; se trouve dans un bloc imbriqué, ce bloc reste inclus dans le corps de la méthode où a existe déjà. Le compilateur détecte ce conflit et affiche une erreur avec une ligne ondulée rouge.
Cette interdiction reste valide même si on change le type de la seconde variable a.

Au sein d’une même portée, les noms de variable doivent être uniques, indépendamment de leur type de données.

Sur l’illustration, la portée de la variable a externe est en jaune et celle de la variable a interne en vert. On voit clairement que la portée externe englobe entièrement la portée interne, ce qui crée le conflit.
La solution est simple : renommer la variable a située à l’intérieur.

Voici un autre exemple à étudier
Est-ce qu’on aura un conflit en écrivant ce code ?
class Program
{
static void Main()
{
int a = 10;
{
double b = 20;
}
{
double b = 30;
}
}
}Langage du code : C# (cs)
La réponse est non. Pourquoi ? Nous avons deux variables nommées b, mais leurs portées ne se chevauchent pas, donc la compilation fonctionne. La première variable b n’existe que dans son propre bloc, la seconde dans un bloc séparé. Aucun conflit ne survient. Regardez l’image ci-dessous.

Les zones colorées montrent la portée de chaque variable b. J’espère que ce point est désormais clair pour vous.
Blocs de code imbriqués et portée des variables