2013-09-24 16 views
5

To jest mój kod:pętli while w języku C# z wielu warunków

while(Func(x) != ERR_D) 
{ 
    if(result == ERR_A) 
     throw...; 
    if(result == ERR_B) 
     throw...; 

    mydata.x = x; 
} 

Problemem jest to, że chcę użyć result = Func(x) w stanie podczas gdy jako wynik zostanie sprawdzone wewnątrz pętli while. Pętla while powinna wywołać Func(x), dopóki nie zwróci ERR_D. Nie mogę korzystać

do{ 
    result = Func(x); 
    if(result == ERR_A) 
     throw ...; 
    if(result == ERR_B) 
     throw ...; 
    mydata.x = x; 
    }while(result != ERR_D); 

w moim projekcie, gdyż najpierw wywołuje Func(x) czyli czego nie chcą. Ale próbowałem while(result = Func(x) != ERR_D), to nie działa. Wszelkie pomysły na rozwiązanie tego problemu?

+2

Dobrze, 'nigdy x' zmienia. Może to ma coś z tym wspólnego? Trudno powiedzieć, ponieważ "nie działa" może oznaczać niemal wszystko, a my nie mamy pojęcia, co powinno się wydarzyć. –

+0

'var result = Func (x); while (result! = ERR_D) {doStuff(); result = Func (x); } '? – Corak

+0

Czy naprawdę ma sens dodawanie wyjątków w pętli while? pętla zakończy się, gdy tylko zostanie rzucona ... –

Odpowiedz

8

Wystarczy dodać kilka nawiasów:

while((result = Func(x)) != ERR_D) { /* ... */ } 

Operator != ma wyższy priorytet niż zadania, dzięki czemu trzeba najpierw zmusić kompilator do wykonania przypisania (które ocenia przypisaną wartość w C#), przed porównaniem wartości po obu stronach operatora != ze sobą. To jest wzór widać dość często, na przykład do odczytu pliku:

string line; 

while ((line = streamReader.ReadLine()) != null) { /* ... */ } 
+0

dobre wyjaśnienie – Heidi

2

Spróbuj tego:

while((result=Func(x)) != ERR_D){ 
if(result == ERR_A) 
     throw...; 
if(result == ERR_B) 
     throw...; 
mydata.x = x; 
} 

UWAGA: przydział odbywa się najpierw w nawiasach (result=Func(x)), to zadanie jest w rzeczywistości wykonane przez przeciążenie operatora = i ten operator zwraca odwołanie do lewej operand boczny, czyli result. Następnie, result zostanie porównane z ERR_D za pośrednictwem operatora !=.

+0

Dzięki, działa. – Heidi

6

Spróbuj podać result poza pętlą, a następnie przypisz mu wartość zwracaną w każdej iteracji.

Na przykład:

var result = Func(x); 

while(result != ERR_D) 
{ 
    if(result == ERR_A) 
     throw...; 
    if(result == ERR_B) 
     throw...; 

    mydata.x = x; 
    result = Func(x); 
} 
1

Spróbuj

while((result = Func(x)) != ERR_D) 
0

Można to wyrazić za pomocą while (true)...:

while (true) 
{ 
    var result = Func(x); 

    if (result == ERR_D) 
     break; 

    if (result == ERR_A) 
     throw ...; 

    if (result == ERR_B) 
     throw ...; 

    mydata.x = x;    
} 

Jest to pętla-z-wyjście (jeżeli zignoruj ​​rzuty;)), więc jest to zorganizowana pętla.

Można również użyć for pętlę, choć wygląda trochę Funky (gra słów nie przeznaczonych!):

for (var result = Func(x); result != ERR_D; result = Func(x)) 
{ 
    if (result == ERR_A) 
     throw ...; 

    if (result == ERR_B) 
     throw ...; 

    mydata.x = x;  
}