Modificatore del parametro out (Riferimenti per C#)

La parola chiave out fa sì che gli argomenti vengono passati per riferimento. Imposta il parametro formale come alias dell'argomento, che deve essere una variabile. In altre parole, qualsiasi operazione sul parametro viene eseguita sull'argomento. È come la parola chiave ref, con la differenza che ref richiede l'inizializzazione della variabile prima di essere passato. È anche come la parola chiave in, con la differenza che in non consente al metodo chiamato di modificare il valore dell'argomento. Per usare un parametro out, la definizione del metodo e il metodo chiamante devono usare in modo esplicito la parola chiave out. Ad esempio:

int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod);     // value is now 44

void OutArgExample(out int number)
{
    number = 44;
}

Nota

La parola chiave out può essere usata anche con un parametro di tipo generico per specificare che il parametro tipo è covariante. Per altre informazioni sull'uso della parola chiave out in questo contesto, vedere out (Modificatore generico).

Le variabili passate come argomenti out non devono essere inizializzate prima di essere passate in una chiamata al metodo. È necessario tuttavia che il metodo chiamato assegni un valore prima della restituzione del metodo.

Le parole chiave in, ref e out non sono considerate parte della firma del metodo ai fini della risoluzione dell'overload. Non è quindi possibile eseguirne l'overload se l'unica differenza è che un metodo accetta un argomento ref o in e l'altro un argomento out. Il codice seguente, ad esempio, non verrà compilato:

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

L'overload è consentito, tuttavia, se un metodo accetta un argomento ref, in o out e l'altro non ha alcuno di questi modificatori, come illustrato di seguito:

class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) => i = 5;
}

Il compilatore sceglie il miglior overload creando una corrispondenza tra i modificatori di parametro nel sito di chiamata e i modificatori di parametro utilizzati nella chiamata al metodo.

Le proprietà non sono variabili e quindi non possono essere passate come parametri out.

Non è possibile usare le parole chiave in, ref e out per i seguenti tipi di metodi:

  • Metodi asincroni definiti usando il modificatore async.

  • Metodi iteratori che includono un'istruzione yield return o yield break.

I metodi di estensione presentano inoltre le restrizioni seguenti:

  • outNon è possibile usare la parola chiave sul primo argomento di un metodo di estensione.
  • Non ref è possibile usare la parola chiave sul primo argomento di un metodo di estensione quando l'argomento non è uno struct oppure un tipo generico non vincolato come uno struct.
  • inNon è possibile usare la parola chiave a meno che il primo argomento non sia uno struct. La in parola chiave non può essere usata in alcun tipo generico, anche quando è vincolato a essere uno struct.

Dichiarazione di parametri out

La dichiarazione di un metodo con argomenti out è un classico espediente per restituire più valori. A partire da C# 7,0, prendere in considerazione le Tuple di valori per scenari simili. Nell'esempio seguente viene usato out per restituire tre variabili con una sola chiamata al metodo. Il terzo argomento è assegnato a null. In questo modo i metodi restituiscono i valori facoltativamente.

void Method(out int answer, out string message, out string stillNull)
{
    answer = 44;
    message = "I've been returned";
    stillNull = null;
}

int argNumber;
string argMessage, argDefault;
Method(out argNumber, out argMessage, out argDefault);
Console.WriteLine(argNumber);
Console.WriteLine(argMessage);
Console.WriteLine(argDefault == null);

// The example displays the following output:
//      44
//      I've been returned
//      True

Chiamata a un metodo con un argomento out

In C# 6 e nelle versioni precedenti è necessario dichiarare una variabile in un'istruzione separata prima di passarla come argomento out. L'esempio seguente dichiara una variabile denominata number prima che venga passata al metodo Int32.TryParse3, che tenta di convertire una stringa in numero.

string numberAsString = "1640";

int number;
if (Int32.TryParse(numberAsString, out number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

A partire da C# 7.0, è possibile dichiarare la variabile out nell'elenco degli argomenti della chiamata al metodo anziché in una dichiarazione di variabile separata. Il codice prodotto risulta più compatto e leggibile e viene impedita l'assegnazione accidentale di un valore alla variabile prima della chiamata al metodo. L'esempio seguente è uguale all'esempio precedente, ad eccezione del fatto che definisce la variabile number nella chiamata al metodo Int32.TryParse.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out int number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

Nell'esempio precedente la variabile number è fortemente tipizzata come int. È anche possibile dichiarare una variabile locale tipizzata in modo implicito, come avviene nell'esempio seguente.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out var number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere la specifica del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.

Vedere anche