2009-09-29 12 views
0

J'ai quelques variables à assigner dans une boucle for. Apparemment, lorsque la boucle se termine, C# ignore tout ce qui s'y est passé et les variables retrouvent leur statut d'origine. Plus précisément, j'ai besoin qu'ils soient les derniers et avant-derniers éléments d'une liste. Voici le code:Problème avec les variables locales en C#

int temp1, temp2; 
for (int i = 0; i < toReturn.Count; i++) { 
    if (i == toReturn.Count - 2) { // Next-to-last element 
     temp1 = toReturn[i]; 
    } else if (i == toReturn.Count - 1) { // Last element 
     temp2 = toReturn[i]; 
    } 
} 
// At this point, temp1 and temp2 are treated as uninitialized 

Remarque: Ignorez les mauvais noms de variables, ce sont vraiment des variables temporaires. Quelque chose de plus complexe pourrait dérouter les choses.

Maintenant, il y a deux façons (que je connais de) de résoudre ceci: l'une consiste à trouver comment faire vivre les variables après la sortie de la boucle, l'autre est de faire quelque chose comme Python temp = my_list[-1] pour obtenir le dernier élément d'une liste. Est-ce que l'un d'entre eux est possible en C#?

Éditer: Lorsque j'essaie de compiler, j'obtiens une erreur «utilisation de la variable locale non affectée 'temp1'». Ce code n'est même pas exécuté, il est simplement assis à l'intérieur d'une méthode qui n'est jamais appelée. Si cela aide, j'essaie d'utiliser les variables dans une autre boucle.

+1

Êtes-vous en train de dire que le compilateur avertit que temp1 et t emp2 ne sont pas initialisés? Ou qu'ils doivent être définis mais ne le sont jamais (la valeur observable n'est pas initialisée)? – Michael

+1

En C#, les variables ne retrouvent pas leur état d'origine après une boucle. Ils conserveront la valeur définie dans la boucle tant que la variable n'a pas été créée dans la boucle. –

Répondre

11

Pourquoi ne pas le faire ...

int temp1 = 0; 
int temp2 = 0; 
    if (toReturn.Count > 1) 
     temp1 = toReturn[toReturn.Count - 2]; 
    if (toReturn.Count > 0) 
     temp2 = toReturn[toReturn.Count - 1]; 
+0

Wow, je n'ai jamais pensé à ça. Je vous remercie. – Javier

+0

+1 pour réfléchir :) –

5

Si toReturn.Count vaut 0, la boucle ne s'exécute jamais et temp1 et temp2 ne sont jamais initialisés.

+0

C'est garanti de ne pas arriver. – Javier

+0

Voyez-vous une erreur ou un avertissement du compilateur? Ou dites-vous que les valeurs observées indiquent qu'il n'a pas été défini? Pour un avertissement de compilateur, le compilateur ne peut pas dire que toReturn.Count est toujours supérieur à 0. – Michael

+4

Cela n'a pas d'importance en ce qui concerne le compilateur, car il ne peut pas raisonnablement prouver qu'il ne se produit jamais, c'est pourquoi il se plaint que les variables soient _initialement non initialisées. Il suffit de les initialiser (par exemple, attribuer 0) lorsque vous les déclarez, et cela va compiler et fonctionner. –

1

Qu'est-ce que cela fait?

if (toReturn.Count > 1) { 
    temp1 = toReturn[toReturn.Count - 2] 
    temp2 = toReturn[toReturn.Count - 1] 
} 
0

essayer de donner temp1 et temp2 une valeur initiale soit 0 ou tout ce qui est approprié, car ils pourraient ne jamais être initialisés

+0

Pour développer: * vous * connaissez temp1 et temp2 seront définies. Votre code le garantit plus ou moins. Mais comme les affectations se produisent à l'intérieur des if-statements, le * compilateur * ne comprend pas que temp1/temp2 sera défini. En ce qui le concerne, il est possible que les instructions If ne soient jamais vraies et que l'assignation ne se produise jamais. – abelenky

0
int temp1 = 0; // Or some other value. Perhaps -1 is appropriate. 
int temp2 = 0; 

for (int i = 0; i < toReturn.Count; i++) { 
    if (i == toReturn.Count - 2) { // Next-to-last element 
     temp1 = toReturn[i]; 
    } else if (i == toReturn.Count - 1) { // Last element 
     temp2 = toReturn[i]; 
    } 
} 

Le compilateur exige que temp1 et temp2 sont certainement affecté avant d'essayer de lire leurs valeurs. Le compilateur ne sait pas que votre for-loop affectera les variables. Il ne sait pas si la boucle for court toujours. Il ne sait pas non plus si vos conditions d'utilisation seront true.

Le code ci-dessus s'assure que temp1 et temp2 ont été affectés à quelque chose. Si vous voulez être sûr que temp1 et temp2 ont été affectés dans la boucle, pensez à garder une trace de ceci:

int temp1 = 0; 
int temp2 = 0; 
bool temp1Assigned = false; 
bool temp2Assigned = false; 

for (int i = 0; i < toReturn.Count; i++) { 
    if (i == toReturn.Count - 2) { // Next-to-last element 
     temp1 = toReturn[i]; 
     temp1Assigned = true; 
    } else if (i == toReturn.Count - 1) { // Last element 
     temp2 = toReturn[i]; 
     temp2Assigned = true; 
    } 
} 
+1

Dans ce cas, Joren, je recommanderais d'utiliser des valeurs nullable plutôt qu'un bool "Affecté". –

+0

Vous avez raison, c'est un meilleur choix. Je n'utilise pas assez les nullables. :) – Joren

0

Si vous voulez une valeur par défaut:

int count = toReturn.Count; 
int temp1 = count > 1 ? toReturn[count - 2] : 0; 
int temp2 = count > 0 ? toReturn[count - 1] : 0; 

Si vous n » t attention à la valeur par défaut et avoir des vérifications précédentes pour le compte en place:

int count = toReturn.Count; 
int temp1 = toReturn[count - 2]; 
int temp2 = toReturn[count - 1]; 
Questions connexes