2010-11-27 17 views
49

In C# 4, c'è un buon modo per avere un parametro di uscita opzionale?Parametri di uscita opzionali

+0

Non visualizzare alcun valore per tale funzione. Se hai mai ascoltato le sessioni dei compilatori di C# su PDC, vedrai che ogni cambiamento ha un significato. –

+29

Non sono d'accordo sul fatto che non ci sia alcun valore in questa funzione. Se un metodo ha qualche logica in esso, BESIDE restituisce i dati tramite parametri esterni - Voglio essere in grado di chiamare questa logica, semplicemente non ho bisogno dell'output ... – Alex

+1

Uso Int32.TryParse() per vedere se la stringa data può essere analizzata in un numero e, se possibile, a volte è tutto ciò che mi interessa. Quindi Jitbit ha ragione. –

risposta

5

No.

per renderlo "optional", nel senso che non è necessario assegnare un valore nel metodo, è possibile utilizzare ref.

+3

Un parametro 'ref' è un caso d'uso molto diverso. Un parametro facoltativo passa in un valore specifico se il chiamante non ne specifica uno: con un parametro ref, il chiamante sta sempre specificando un valore, indipendentemente dal fatto che lo abbia specificato o meno. Il 'ref' punta sempre a una posizione di memoria valida, e una posizione di memoria valida contiene sempre _qualcosa_. Nella migliore delle ipotesi, questo è solo un valore magico senza il vantaggio di una specifica predefinita che dice "il valore predefinito è X". – danwyand

+2

Sì, questa risposta non è un giudizio di progettazione, motivo per cui ho aggiunto il qualificatore "nel senso che". – codekaizen

48

Non proprio, anche se è sempre possibile sovraccaricare il metodo con un altro che non accetta il parametro di uscita.

+3

qualsiasi idea su come gestire il parametro opzionale in modo più elegante di '{stringa dummy; return Foo (out dummy); } 'nel sovraccarico che non accetta il parametro di uscita? –

+2

@Louis: No, probabilmente è quello che avrei fatto! – Cameron

+0

Questo è un codice in più per la piastra della caldaia. – Brain2000

2
private object[] Func(); 

assegnare quante uscite opzionali desiderate nella matrice di oggetti di restituzione e quindi usarle! ma se vuoi dire qualcosa di uscita opzionale come

private void Func(out int optional1, out string optional2) 

e quindi si chiama qualcosa come

Func(out i); 

allora la risposta è no non puoi. anche C# e .NET framework hanno molte strutture dati molto flessibili come List e Array e possono essere utilizzate come parametro di output o come tipo restituito, quindi non è necessario implementare un modo per avere parametri di output opzionali.

7

Anche la decorazione dei parametri con OptionalAttribute non funziona. Per estendere il campione precedente, si otterrebbe qualcosa del tipo:

private void Func(
    [Optional] out int optional1, 
    [Optional] out string optional2) 
{ /* ... */ } 

Si noti che quanto sopra verrà compilato (forse sfortunatamente). Tuttavia, il tentativo di compilare:

Func(out i); 

non riuscirà a meno che non sia esplicitamente previsto un sovraccarico con una firma ad un parametro.

Per (teoricamente) rendere il lavoro di cui sopra è un problema significativo. Quando viene chiamato un metodo con un parametro facoltativo omesso, viene creato un frame di stack contenente i valori di tutti i parametri e i valori mancanti vengono semplicemente riempiti con i valori predefiniti specificati.

Tuttavia, un parametro "out" è un riferimento, non un valore. Se quel parametro è opzionale e non viene fornito, quale variabile farà riferimento? Il compilatore deve ancora applicare il requisito che il parametro "out" venga compilato prima di ogni ritorno normale dal metodo, poiché il compilatore non sa a priori quali (se esistono) parametri opzionali sono specificati da un chiamante. Ciò significa che un riferimento alla variabile fittizia da qualche parte dovrebbe essere passato in modo che il metodo abbia qualcosa da riempire. Gestire questo spazio variabile fittizio creerebbe un fastidioso mal di testa per lo scrittore del compilatore. Non sto dicendo che sarebbe impossibile elaborare i dettagli di come funzionerebbe, ma le implicazioni architettoniche sono abbastanza grandi che Microsoft ha comprensibilmente trasmesso questa funzione.

0
public class Dummy<T> 
{ 
    public T Value; 
} 

Quindi utilizzare functionDoSomething(out new Dummy<int>().Value, dove int potrebbe essere qualsiasi tipo.

Problemi correlati