Perché le linee guida del framework .Net raccomandano di non usare argomenti ref / out?

StackOverflow https://stackoverflow.com/questions/214688

  •  03-07-2019
  •  | 
  •  

Domanda

Apparentemente, stanno "confondendo". È davvero questo il motivo? Riesci a pensare ad altri?

È stato utile?

Soluzione

Hai visto quanti sviluppatori non capiscono veramente ref / out?

Li uso dove sono realmente necessari, ma non diversamente. Di solito sono utili solo se si desidera restituire effettivamente due o più valori, nel qual caso vale la pena almeno pensare se esiste un modo per fare in modo che il metodo faccia solo una cosa. A volte l'uso di ref / out è l'approccio più appropriato - i vari metodi TryParse ecc.

Altri suggerimenti

A mio avviso, sono considerati un odore di codice perché in generale esiste un'opzione molto migliore: restituire un oggetto.

Se noti, nella libreria .NET sono usati solo in alcuni casi speciali, vale a dire tryparse scenari simili dove:

  • restituire una classe significherebbe inscatolare un tipo di valore
  • il contratto del metodo richiede che sia veloce, quindi boxe / unboxing non è un'opzione praticabile.

ref / out significa automaticamente mutabilità e la programmazione funzionale con valori immutabili è di gran moda in questi giorni. Prova a inserire una chiamata a Dictionary. TryGetValue in una query LINQ. L'API richiede la dichiarazione di variabili e rovina qualsiasi 'fluidità' nell'API.

Questo non vuol dire che questo è "il motivo", ma è un esempio di "un motivo".

(Vedi anche

http://lorgonblog.spaces.live.com/blog /cns!701679AD17B6D310!181.entry

per commenti su come i linguaggi funzionali gestiscono tali API.)

La confusione è probabilmente il motivo migliore. Confondere significa diminuire la manutenibilità e aumentare la probabilità di introdurre bug sottili. Li vedo in una vista simile a "vai a" dichiarazione del flusso di controllo. Sebbene non sia intrinsecamente negativo di per sé, nel corso dei decenni ha portato a molti programmi impossibili da leggere / comprendere.

Stai lontano da tutto ciò che può rendere il tuo codice più confuso di quanto debba essere.

Detto questo, quelle parole chiave esistono probabilmente perché gli sviluppatori del framework hanno visto la necessità di tali cose. Usali se non esiste una soluzione adeguata, ma evitali quando puoi.

Anche

ref / out non funziona con " Func " delegati, quindi queste API di stile sono meno componibili / riutilizzabili con alcune altre API che utilizzano delegati.

Solo un pensiero, trovo che ref / out sia utile quando gli argomenti catturano lo stato di esecuzione nel metodo target piuttosto che catturare i dati restituiti. Considerare uno scenario in cui si desidera ottenere un messaggio di errore da un servizio che restituisce l'oggetto Cliente.

Customer GetCustomerById(int id, out string errorMessage);

Se questo metodo fallisce, è probabile che si restituisca un oggetto Cliente null o si generasse un'eccezione. Tuttavia, se voglio conoscere la causa dell'errore (validazione? Database?), Userei l'argomento. L'argomento errorMessage qui non ha nulla a che fare con i dati, semplicemente usato per catturare ciò che non va nell'esecuzione del metodo.

Personalmente se avessi un metodo che dovrebbe restituire due o più dati / valori essenziali, ripenserei il design del mio codice.

Il motivo per cui mi è stato detto è che il GC 1.0 ha avuto problemi quando è stato usato ref / out. Il GC in 2.0 (e probabilmente neanche 1.1) non ha questi problemi, quindi normalmente suppongo che sia un'eredità ormai non utile.

@TraumaPony Va bene se ci dai una fonte (URL o qualcosa del genere) a queste linee guida del framework .NET.

Dovresti restituire oggetti è probabilmente il motivo più probabile per cui suggeriscono di non usare ref o out.

" ref " deve davvero essere usato solo quando si passano valori scalari, ma vedo che le persone lo usano spesso per oggetti che vengono comunque passati per riferimento.

La complessità del codice non è sufficiente? Confronto:

int myValue;
ReadFromSomewhere(ref myValue);

A:

int myValue = ReadFromSomewhere();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top