Domanda

Cerco una risposta chiara, concisa e precisa.

Idealmente come risposta effettiva, anche se sono benvenuti collegamenti a buone spiegazioni.

Questo vale anche per VB.Net, ma le parole chiave sono diverse: ByRef E ByVal.

È stato utile?

Soluzione

Per impostazione predefinita (in C#), passando un oggetto a una funzione si passa effettivamente una copia del riferimento a quell'oggetto.La modifica del parametro stesso modifica solo il valore del parametro e non la variabile specificata.

void Test1(string param)
{
    param = "new value";
}

string s1 = "initial value";
Test1(s1);
// s1 == "initial value"

Utilizzando out O ref passa un riferimento alla variabile specificata nella chiamata alla funzione.Eventuali modifiche al valore di an out O ref il parametro verrà restituito al chiamante.

Entrambi out E ref si comportano in modo identico tranne che per una leggera differenza: ref i parametri devono essere inizializzati prima della chiamata, mentre out i parametri possono essere non inizializzati.Per estensione, ref è garantito che i parametri vengano inizializzati all'inizio del metodo, mentre out i parametri vengono trattati come non inizializzati.

void Test2(ref string param)
{
    param = "new value";
}

void Test3(out string param)
{
    // Use of param here will not compile
    param = "another value";
}

string s2 = "initial value";
string s3;
Test2(ref s2);
// s2 == "new value"
// Test2(ref s3); // Passing ref s3 will not compile
Test3(out s2);
// s2 == "another value"
Test3(out s3);
// s3 == "another value"

Modificare:COME d.p sottolinea, la differenza tra out E ref viene applicato solo dal compilatore C#, non da CLR.Per quanto ne so, VB non ha equivalenti per out e implementa ref (COME ByRef), corrispondente al sostegno del CLR.

Altri suggerimenti

Una nota aggiuntiva su rif vs.fuori:La distinzione tra i due viene applicata dal compilatore C#.Il CLR non distingue tra out e ref.Ciò significa che non è possibile avere due metodi le cui firme differiscono solo per un out o un ref

void foo(int value) {}

// Only one of the following would be allowed

// valid to overload with ref
void foo(ref int value) {}

// OR with out
void foo(out int value) {}

out significa che il parametro verrà inizializzato con il metodo:

int result; //not initialised

if( int.TryParse( "123", out result ) )
   //result is now 123
else
   //if TryParse failed result has still be 
   // initialised to its default value (0)

ref forzerà il passaggio del riferimento sottostante:

void ChangeMyClass1( MyClass input ) {
   input.MyProperty = "changed by 1";
   input = null;
   //can't see input anymore ... 
   // I've only nulled my local scope's reference
}

void ChangeMyClass2( ref MyClass input ) {
   input.MyProperty = "changed by 2";
   input = null;
   //the passed reference is now null too.
}

MyClass tester = new MyClass { MyProperty = "initial value" };

ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"

ChangeMyClass2( ref tester );
// now tester is null

Anche una delle mie domande su StackOverflow gestisce questo argomento.
Gestisce circa "passaggio per riferimento" e "passaggio per valore" in diversi tipi di lingue, c# è incluso quindi forse puoi trovare qualche informazione extra anche lì.

Fondamentalmente si tratta di:

  • rif:verrà passato il parametro con la parola chiave ref come riferimento
  • fuori:il parametro con la parola chiave out verrà trattato come un file parametro di uscita

ma questa è davvero la risposta più elementare che puoi dare, poiché è un po' più complessa di quanto affermato qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top