Differenza tra i parametri ref e out in .NET

Qual è la differenza tra out parametri ref e out in .NET? Quali sono le situazioni in cui uno può essere più utile dell’altro? Quale sarebbe uno snippet di codice in cui è ansible utilizzarne uno e un altro no?

Sono praticamente la stessa cosa: l’unica differenza è che una variabile passata come parametro out non ha bisogno di essere inizializzata ma passandola come parametro ref deve essere impostata su qualcosa.

 int x; Foo(out x); // OK int y; Foo(ref y); // Error: y should be initialized before calling the method 

Ref parametri Ref sono per i dati che possono essere modificati, out parametri out sono per i dati che sono un output aggiuntivo per la funzione (ad esempio int.TryParse ) che stanno già utilizzando il valore restituito per qualcosa.

Perché C # ha sia “ref” che “out”?

Il chiamante di un metodo che accetta un parametro out non è necessario da assegnare alla variabile passata come parametro out prima della chiamata; tuttavia, il chiamato deve assegnarsi al parametro out prima di tornare.

In contrasto i parametri di riferimento sono considerati inizialmente assegnati dal chiamante. Pertanto, non è necessario che il callee assegni il parametro ref prima dell’uso. I parametri di riferimento vengono passati sia dentro che fuori da un metodo.

Quindi, out significa fuori, mentre ref è per dentro e fuori.

Questi corrispondono strettamente ai parametri [out] e [in,out] delle interfacce COM, i vantaggi dei parametri out sono che i chiamanti non devono passare un object preassegnato nei casi in cui non è necessario dal metodo chiamato – questo evita sia il costo di allocazione, sia qualsiasi costo che potrebbe essere associato al marshalling (più probabile con COM, ma non insolito in .NET).

ref e out consentono entrambi al metodo chiamato di modificare un parametro. La differenza tra loro è ciò che accade prima di effettuare la chiamata.

  • ref significa che il parametro ha un valore su di esso prima di entrare nella funzione. La funzione chiamata può leggere o modificare il valore in qualsiasi momento. Il parametro entra, quindi esce

  • out significa che il parametro non ha valore ufficiale prima di entrare nella funzione. La funzione chiamata deve inizializzarla. Il parametro si spegne

Ecco il mio modo preferito per guardarlo: ref è passare le variabili per riferimento. out è dichiarare un valore di ritorno secondario per la funzione. È come se potessi scrivere questo:

 // This is not C# public (bool, string) GetWebThing(string name, ref Buffer paramBuffer); // This is C# public bool GetWebThing(string name, ref Buffer paramBuffer, out string actualUrl); 

Ecco un elenco più dettagliato degli effetti di ciascuna alternativa:

Prima di chiamare il metodo:

ref : il chiamante deve impostare il valore del parametro prima di passarlo al metodo chiamato.

out : il metodo del chiamante non è necessario per impostare il valore dell’argomento prima di chiamare il metodo. Molto probabilmente, non dovresti. In effetti, qualsiasi valore corrente viene scartato.

Durante la chiamata:

ref : il metodo chiamato può leggere l’argomento in qualsiasi momento.

out : il metodo chiamato deve inizializzare il parametro prima di leggerlo.

Chiamate remote:

ref : il valore corrente viene eseguito il marshalling alla chiamata remota. Costo extra di prestazioni.

out : non viene passato nulla alla chiamata remota. Più veloce.

Dal punto di vista tecnico, è ansible utilizzare sempre il ref in luogo out , ma out consente di essere più precisi sul significato dell’argomento e, a volte, può essere molto più efficiente.

Esempio per OUT: la variabile ottiene il valore inizializzato dopo essere entrato nel metodo. Successivamente lo stesso valore viene restituito al metodo principale.

 namespace outreftry { class outref { static void Main(string[] args) { yyy a = new yyy(); ; // u can try giving int i=100 but is useless as that value is not passed into // the method. Only variable goes into the method and gets changed its // value and comes out. int i; a.abc(out i); System.Console.WriteLine(i); } } class yyy { public void abc(out int i) { i = 10; } } } 

Produzione:

10

===============================================

Esempio per Ref: La variabile deve essere inizializzata prima di entrare nel metodo. Successivamente, lo stesso valore o valore modificato verrà restituito al metodo principale.

 namespace outreftry { class outref { static void Main(string[] args) { yyy a = new yyy(); ; int i = 0; a.abc(ref i); System.Console.WriteLine(i); } } class yyy { public void abc(ref int i) { System.Console.WriteLine(i); i = 10; } } } 

Produzione:

  0 10 

=================================

Spero che sia chiaro ora.

  • Una variabile ref deve essere inizializzata prima di passarla.
  • Una variabile out deve essere impostata nell’implementazione della funzione
  • out parametri out possono essere considerati come variabili di ritorno aggiuntive (non inserite)
  • ref parametri ref possono essere considerati sia come variabili di input che di output.

Parametri Ref e Out:

I parametri out e ref sono usati per restituire valori nella stessa variabile, che tu passi come argomento di un metodo. Questi due parametri sono molto utili quando il tuo metodo deve restituire più di un valore.

È necessario assegnare un valore al parametro out nel corpo del metodo calee, altrimenti il ​​metodo non verrà compilato.


Parametro Ref: deve essere inizializzato prima di passare al Metodo. La parola chiave ref su un parametro metodo fa sì che un metodo faccia riferimento alla stessa variabile che è stata passata come parametro di input per lo stesso metodo. Se si apportano modifiche alla variabile, si rifletteranno nella variabile.

 int sampleData = 0; sampleMethod(ref sampleData); 

Es. Del parametro di riferimento

 public static void Main() { int i = 3; // Variable need to be initialized sampleMethod(ref i ); } public static void sampleMethod(ref int sampleData) { sampleData++; } 

Out Parameter: Non è necessario essere inizializzati prima di passare a Method. Il parametro out può essere utilizzato per restituire i valori nella stessa variabile passati come parametro del metodo. Eventuali modifiche apportate al parametro si rifletteranno nella variabile.

  int sampleData; sampleMethod(out sampleData); 

Ex of Out Parametro

 public static void Main() { int i, j; // Variable need not be initialized sampleMethod(out i, out j); } public static int sampleMethod(out int sampleData1, out int sampleData2) { sampleData1 = 10; sampleData2 = 20; return 0; } 

su:

In C #, un metodo può restituire solo un valore. Se desideri restituire più di un valore, puoi utilizzare la parola chiave out. Il modificatore out ritorna come ritorno per riferimento. La risposta più semplice è che la parola chiave “out” è usata per ottenere il valore dal metodo.

  • Non è necessario inizializzare il valore nella funzione di chiamata.
  • È necessario assegnare il valore nella funzione chiamata, altrimenti il ​​compilatore segnalerà un errore.

ref:

In C #, quando si passa un tipo di valore come int, float, double ecc. Come argomento al parametro method, viene passato per valore. Pertanto, se si modifica il valore del parametro, questo non influisce sull’argomento nella chiamata al metodo. Ma se si contrassegna il parametro con la parola chiave “ref”, si rifletterà nella variabile attuale.

  • È necessario inizializzare la variabile prima di chiamare la funzione.
  • Non è obbligatorio assegnare alcun valore al parametro ref nel metodo. Se non si modifica il valore, qual è la necessità di contrassegnarlo come “ref”?

I parametri di riferimento non devono essere impostati nella funzione, mentre i parametri out devono essere associati a un valore prima di uscire dalla funzione. Le variabili passate come out possono anche essere passate a una funzione senza essere inizializzate.

out specifica che il parametro è un parametro di output, ovvero non ha valore finché non viene impostato esplicitamente dal metodo.

ref specifica che il valore è un riferimento che ha un valore e il cui valore è ansible modificare all’interno del metodo.

out parametri out vengono inizializzati con il metodo chiamato, i parametri ref vengono inizializzati prima di chiamare il metodo. Pertanto, out parametri out vengono utilizzati quando è necessario ottenere un valore di ritorno secondario, i parametri ref vengono utilizzati per ottenere un valore e potenzialmente restituire una modifica a tale valore (in secondo luogo al valore di ritorno principale).

La parola chiave ref viene utilizzata per passare i valori per riferimento. (Questo non preclude che i valori passati siano tipi di valore o tipi di riferimento). I parametri di output specificati con la parola chiave out sono per restituire valori da un metodo.

Una differenza chiave nel codice è che è necessario impostare il valore di un parametro di output all’interno del metodo. Questo non è il caso dei parametri ref.

Per ulteriori dettagli, consultare http://www.blackwasp.co.uk/CSharpMethodParameters.aspx

Un parametro out è un parametro ref con un attributo speciale Out() aggiunto. Se un parametro per un metodo C # è dichiarato come out , il compilatore richiederà che il parametro venga scritto prima che possa essere letto e prima che il metodo possa tornare. Se C # chiama un metodo il cui parametro include un attributo Out() , il compilatore, per decidere se segnalare errori di “variabile non definita”, pretende che la variabile sia scritta immediatamente prima di chiamare il metodo. Nota che poiché altri linguaggi .net non attribuiscono lo stesso significato all’attributo Out() , è ansible che chiamare una routine con un parametro out lasci la variabile in questione inalterata. Se una variabile viene utilizzata come parametro out prima che sia definitivamente assegnata, il compilatore C # genererà il codice per assicurarsi che venga cancellato prima che venga utilizzato, ma se tale variabile lascia e rientra nello scope, non c’è garanzia che verrà ripulito.

ref probabilmente si sposterà su null poiché presumibilmente si aspetta di modificare un object esistente. out si aspetta nulla, poiché restituisce un nuovo object.

out e ref sono esattamente gli stessi con l’eccezione che le variabili out non devono essere inizializzate prima di inviarle nell’abisso. Non sono così intelligente, l’ho criptato dalla libreria MSDN :).

Per essere più espliciti sul loro utilizzo, tuttavia, il significato del modificatore è che se si modifica il riferimento di tale variabile nel proprio codice, out e ref causeranno la variabile chiamante a cambiare anche il riferimento. Nel codice qui sotto, la variabile ceo sarà un riferimento al newGuy una volta che ritornerà dalla chiamata a doStuff. Se non fosse per ref (o out) il riferimento non sarebbe cambiato.

 private void newEmployee() { Person ceo = Person.FindCEO(); doStuff(ref ceo); } private void doStuff(ref Person employee) { Person newGuy = new Person(); employee = newGuy; } 

Questo out e ref Paramerter in C # ha alcuni buoni esempi.

La differenza fondamentale delineata è che out parametri out non devono essere inizializzati quando vengono passati, mentre i parametri ref lo fanno.

Quando un parametro out viene dichiarato nella dichiarazione del metodo, il corpo del metodo deve assegnare un valore alla variabile out prima di ritornare. Quindi è responsabilità del metodo chiamato assegnare il valore al parametro out prima che ritorni.

Quando un parametro ref viene dichiarato nel metodo, l’argomento che viene passato durante il richiamo del metodo deve aver assegnato il valore. Quindi è responsabilità del chiamante assegnare il valore per l’argomento ref prima di chiamare il metodo.

Sono sottilmente diversi.

Un parametro out non deve essere inizializzato dal callee prima di essere passato al metodo. Pertanto, qualsiasi metodo con un parametro out

  • Imansible leggere il parametro prima di assegnargli un valore
  • Deve assegnare un valore ad esso prima di tornare

Questo è usato per un metodo che deve sovrascrivere il suo argomento indipendentemente dal suo valore precedente.


Un parametro ref deve essere inizializzato dal callee prima di passarlo al metodo. Pertanto, qualsiasi metodo con un parametro ref

  • Può ispezionare il valore prima di assegnarlo
  • Può restituire il valore originale, intatto

Questo è usato per un metodo che deve (es.) Ispezionare il suo valore e convalidarlo o normalizzarlo.

out ha ottenuto una nuova syntax più syntax in C # 7 https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#more-expression-bodied-members e molto altro ancora eccitante è il miglioramento della tupla C # 7 che è una scelta più elegante rispetto all’utilizzo di ref e out IMHO.