133 votes

C# variable déclarée dans cycle est variable locale ?

J’ai été en utilisant c# pour pas mal de temps mais jamais réalisé suivant :

Alors pourquoi je ne peux pas utiliser la valeur de « i » en dehors du bloc si elle ne me permet pas de déclarer une variable avec ce nom ? J’ai pensé que cette variable utilisée par cycle est valide uniquement dans son champ d’application.

119voto

J.Kommer Points 4560

La raison pour laquelle vous n'êtes pas autorisé à définir une variable avec le même nom dans la boucle for aswell comme à l'extérieur de la boucle for est parce que les variables dans l'avant-champ d'application sont valables à l'intérieur de la portée. Sens qu'il y aurait deux " i " variables à l'intérieur de la boucle for si cela était autorisé.

Voir: MSDN Étendues

Plus précisément:

La portée d'une variable locale déclarée dans un local-variable-déclaration (Section 8.5.1) est le bloc dans lequel la déclaration se produit.

et

La portée d'une variable locale déclarée dans un initialiseur de un pour déclaration (Section 8.8.3) est l'initialiseur, l'état, l'itérateur, et le contenu de l'instruction de la déclaration.

Et aussi: Local des déclarations de variables (Section 8.5.1 de la spécification C#)

Plus précisément:

La portée d'une variable locale déclarée dans un local-variable-déclaration est le bloc dans lequel la déclaration se produit. C'est une erreur de se référer pour une variable locale dans une position textuelle qui précède le local variable de demande de déclaration de la variable locale. Dans le cadre d'un variable locale, c'est une erreur de compilation pour déclarer un autre local variable ou constante avec le même nom.

(C'est moi qui souligne.)

Ce qui signifie que le champ d'application de l' i à l'intérieur de votre boucle, la boucle for. Alors que le champ d'application de l' i en dehors de ta boucle for est la totalité de la principale méthode de plus pour la boucle. Ce qui signifie que vous auriez deux occurrences de i à l'intérieur de la boucle qui n'est pas valide conformément à la ci-dessus.

La raison pour laquelle vous n'êtes pas autorisé à le faire int A = i; est parce qu' int i n'est portée pour l'utilisation dans l' for boucle. Ainsi, il n'est plus accessible de l'extérieur de l' for boucle.

Comme vous pouvez le voir sur ces deux questions sont le résultat de la portée; la première question (int i = 4;) entraînerait deux i variables au sein de l' for boucle portée. Alors qu' int A = i; entraînerait l'accès à une variable qui est hors de portée.

Ce que vous pourriez faire à la place est de déclarer i à être étendue à l'ensemble de la méthode, et ensuite l'utiliser dans la méthode ainsi que la boucle for de la portée. Cela permettra d'éviter de casser la règle.

    public static void Main()
    {
        int i;

        for (i = 0; i < 5; i++)
        {

        }

        i = 4;  // 'i' is only declared in the method scope now, no longer in the child scope -> valid.

        int A = i;  // 'i' is declared in the method's scope -> valid. 
    }

EDIT:

Le compilateur C# pourrait bien sûr être modifié pour permettre ce code pour compiler tout à fait valablement. Après tout, c'est valide:

        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(i);
        }

        for (int i = 5; i > 0; i--)
        {
            Console.WriteLine(i);
        }

Mais serait-il vraiment bénéfique pour votre code lisibilité et la maintenabilité d'être capable d'écrire le code tel que:

    public static void Main()
    {
        int i = 4;

        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(i);
        }

        for (int i = 5; i > 0; i--)
        {
            Console.WriteLine(i);
        }

        Console.WriteLine(i);
    }

Pensez à le potentiel pour des erreurs ici, la dernière i imprimer 0 ou 4? Maintenant, c'est un tout petit exemple, celui qui est assez facile à suivre et piste, mais il est certainement beaucoup moins facile à gérer et lisible qu'après avoir déclaré que l'extérieur de la i par un nom différent.

N. B:

Veuillez noter, C#'s règles de portée diffèrent de C++de règles de portée. En C++ les variables sont uniquement dans la portée de l'endroit où ils sont déclarés jusqu'à la fin du bloc. Ce qui rendrait votre code valide construire en C++.

29voto

Eric Lippert Points 300275

J. Kommer réponse est bonne: en bref, il est illégal pour une variable locale à être déclarées dans une déclaration de variable locale de l'espace qui chevauche une autre déclaration de variable locale de l'espace qui a un local du même nom.

Il existe une règle supplémentaire de C# qui est violé. La règle supplémentaire est qu' il est illégal pour un simple nom qui doit être utilisé pour faire référence à deux entités différentes à l'intérieur de deux différentes qui se chevauchent déclaration de variable locale des espaces. N'est donc pas seulement votre exemple illégal, c'est illégal:

class C
{
    int x;
    void M()
    {
        int y = x;
        if(whatever)
        {
            int x = 123;

Parce que maintenant le simple nom de "x" a été utilisé à l'intérieur de la déclaration de variable locale de l'espace de "y" pour signifier deux choses différentes -- "ce.x" et le "x".

Voir http://blogs.msdn.com/b/ericlippert/archive/tags/simple+les noms de/ pour une analyse plus approfondie de ces questions.

13voto

Chris S Points 32376

Il existe un moyen de déclarer et de l’utilisation `` à l’intérieur de la méthode après la boucle :

Vous pouvez le faire en Java (il peut-être provenir de C je ne suis pas sûr). Bien sûr, c’est un peu brouillon dans un souci d’un nom de variable.

7voto

Widor Points 7307

Si vous l’aviez déclarée *avant* votre boucle, pensez-vous qu’il soit encore valide pour la déclarer à l’intérieur de la boucle ?

Non, car alors la portée des deux chevaucherait.

Comme pour ne pas être capable de faire , Eh bien c’est tout simplement parce que n’existe que dans le `` en boucle, comme il devrait le faire.

7voto

ChrisBD Points 5795

En plus de J. Kommer de réponse (+1 btw). Il y a cette dans la norme pour la portée:

bloc Si vous déclarez une variable dans un bloc de construction comme une instruction if, cette variable a une portée jusqu'à la fin du bloc. La durée de vie est jusqu'à la fin de la procédure.

Procédure Si vous déclarez une variable à l'intérieur d'une procédure, mais en dehors de toute instruction if, le champ d'application est jusqu'à la Fin ou à la Fin de la Sous Fonction. La durée de vie de la variable est jusqu'à ce que les procédures se termine.

Ainsi, l'int i decalared à l'intérieur de la boucle for en-tête sera portée uniquement au cours de la boucle de bloc, MAIS c'est à vie dure jusqu'à ce que l' Main() code terminée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X