Vicino alla soluzione "Mondo ideale"
Quanto segue è C # valido
public static void Main()
{
var i = 0;
string value;
while ((value = GetValue(i++)) != null)
{
DoSomethingWith(value);
}
}
private static string GetValue(int input)
{
if (input > 20)
{
return null;
}
return input.ToString();
}
private static void DoSomethingWith(string value)
{
Console.WriteLine(value);
}
Confronta con il tuo "scenario ideale del mondo":
var i = 0;
while((var value = GetValue(i++)) != null)
{
DoSomethingWith(value);
}
Tutto quello che dovevo fare era tirare value
fuori dal ciclo. Sembri disposto a farlo per tutte le alternative presentate. Quindi, non penso che sia troppo lungo.
"Infinito" Mentre alternativo
Ho giocato con le alternative ... eccone un'altra:
var i = 0;
while (true)
{
var value = GetValue(i++);
if (value == null)
{
break;
}
DoSomethingWith(value);
}
In questo caso puoi dichiarare value
all'interno del ciclo (e usando var
), non devi controllare per due volte null
, non devi chiamare GetValue
due volte con lo stesso input e non devi creare un wrapper con un parametro out
.
Alternativa utilizzando
Potremmo provare ad esprimere la stessa cosa usando un ciclo for
. Anche se l'approccio ingenuo non funziona:
// I repeat, this does not work:
var i = 0;
for (string value = null; value != null; value = GetValue(i++))
{
DoSomethingWith(value);
}
Il problema con questa versione è che inizia con value
che è null
, che soddisfa il criterio di uscita, e quindi non ottieni iterazioni.
Come JimmyJames sottolinea puoi scriverlo come in questo modo:
var i = 0;
for(string value; (value = GetValue(i++)) != null;)
{
DoSomethingWith(value);
}
L'unico inconveniente che vedo è che devi scrivere il tipo (non puoi usare var
).
Addendum : questa è un'altra variante suggerito da Maliafo :
var i = 0;
for (var value = GetValue(i); value != null; value = GetValue(++i))
{
DoSomethingWith(value);
}
Sebbene questa versione richieda di scrivere GetValue
, non la chiamerà due volte con lo stesso valore.
Vuoi dichiarare anche i
nello scope? Dai un'occhiata a questo:
for (var i = 0; ; i++)
{
var value = GetValue(i);
if (value == null)
{
break;
}
DoSomethingWith(value);
}
Questo è lo stesso ciclo che vediamo nell'infinito mentre la soluzione che ho postato sopra. Tuttavia, dal momento che non ho avuto alcuna condizione al momento ... perché non usare cambiarlo in for
per incrementare i
?
Addendum : vedi anche la risposta di NetMage per un uso interessante delle funzionalità di C # 7.0 .