Prima di .net, un modello normale era per i metodi TryXX
per lasciare semplicemente l'argomento passato per riferimento non modificato. Questo è stato un modello molto utile, dal momento che ha fatto sì che il codice che ha voluto utilizzare un valore di default potrebbe fare qualcosa di simile:
MyNum = 5;
TryParsing(myString, &myNum);
mentre il codice che non si desidera utilizzare un valore predefinito potrebbe utilizzare:
if (TryParsing(myString, &myNum))
{ .. code that uses myNum .. }
else
{ .. code that doesn't use myNum .. }
Nel primo utilizzo, il codice chiamante avrebbe dovuto garantire l'inizializzazione di myNum
prima della chiamata, ma non avrebbe dovuto preoccuparsi del valore di ritorno TryParsing
. Nell'ultimo utilizzo, il codice chiamante dovrebbe preoccuparsi del valore restituito, ma non dovrebbe inizializzare myNum
prima della chiamata. La stessa routine TryParsing
non dovrebbe preoccuparsi dell'uso previsto.
C# non consente molto un tale modello, tuttavia, a meno che lo TryParsing
non sia scritto in un'altra lingua. O TryParsing
deve essere scritto in modo tale che il valore precedente di myNum
venga sovrascritto senza condizioni senza essere stato esaminato, il chiamante deve inizializzarlo incondizionatamente o devono essere forniti metodi diversi per i due scenari. Se il metodo TryParsing
è stato scritto in un altro linguaggio, potrebbe in teoria comportarsi come i metodi vecchio stile (scrivere l'argomento in caso di successo e lasciarlo da solo se non lo è) mentre lo si chiama ancora un parametro out
. Non lo consiglierei, tuttavia, perché il comportamento bizzarro non sarebbe limitato a quel parametro out
.
Si consideri, per esempio, che un metodo di quello stile utilizzato un argomento di tipo fooStruct
, e fooStruct
aveva un costruttore che sembrava:
fooStruct(string st)
{
fooStruct.TryParse(st, out this);
}
Il compilatore sarebbe perfettamente felice con una tale costruttore, dal momento che "sicuramente" scrive this
. D'altra parte, se qualche altro codice fa:
while(someCondition)
{
var s = new fooStruct(someString);
...
}
Ci si potrebbe aspettare che s
si sono titolari di una struttura inizializzata (se someString
è valido) oppure essere vuoto (se non lo è). Nulla su quel codice suggerirebbe che s
potrebbe mantenere il suo valore tra le ripetizioni del ciclo. Ciò nonostante, è esattamente ciò che potrebbe accadere.
Inoltre, se il risultato ti interessa abbastanza da non voler utilizzare il valore predefinito, a meno che non fosse esplicitamente il valore che era XYZ (analizzato, ecc.), quindi dovresti davvero controllare il valore di ritorno dal metodo in ogni caso. –
Non avevo pensato che il consumatore avesse un motivo per usare il valore restituito se Prova restituito falso. –