Co ref, val az mysli na parametry metody?

hlasů
21

Sháním jasným, výstižným a přesné odpovědi.

V ideálním případě se jako skutečná odpověď, přestože odkazy na dobré vysvětlení vítány.

To platí i pro VB.Net, ale klíčová slova jsou odlišné - ByRefa ByVal.

Položena 16/08/2008 v 09:46
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
26

Ve výchozím nastavení (v jazyce C #), předáním objektu na funkci ve skutečnosti předá kopii odkazu na tento objekt. Změna parametru sám mění pouze hodnotu parametru, a nikoli variabilní, který byl zadán.

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

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

Použitím outnebo refpředá odkaz na proměnné specifikované ve volání funkce. Jakékoliv změny v hodnotě jako outnebo refparametru budou předány zpět k volajícímu.

Obě outa refchovají identicky s výjimkou jednoho mírným rozdílem: refjsou vyžadovány parametry inicializovat před voláním, zatímco outparametry mohou být zovaných. V širším smyslu refjsou zaručeny parametry, které se inicializace na začátku způsobu, přičemž outparametry jsou považovány za zovaných.

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"

Edit : Jako dp poukazuje na to, rozdíl mezi outa refje vynuceno pouze C # kompilátor, nikoli CLR. Pokud je mi známo, VB nemá ekvivalent pro outa nářadí ref(as ByRef) pouze odpovídající podporu CLR.

Odpovězeno 16/08/2008 v 13:06
zdroj uživatelem

hlasů
7

Jeden další poznámka o ref versus out: Rozdíl mezi oběma druhy je vynuceno C # kompilátor. CLR nerozlišuje mezi ven a referenčního čísla pozice. To znamená, že nemůžete mít dvě metody, jejichž podpisy se liší pouze tím, out nebo 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) {}
Odpovězeno 16/08/2008 v 13:32
zdroj uživatelem

hlasů
3

out znamená, že parametr bude inicializována způsobem:

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 donutí základní reference, které mají být předány:

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
Odpovězeno 16/08/2008 v 09:49
zdroj uživatelem

hlasů
2

Jeden z mých vlastních otázek na StackOverflow zpracovává toto téma příliš.
To se zabývá o „kolem odkazu“ a „předat podle hodnoty“ v různých typů jazyků, c # je zahrnuta , takže možná si můžete najít nějaké další informace i tam.

V podstatě jde o to, aby:

  • ref: parametr s uvedením referenčního čísla klíčového slova budou předány formou odkazu
  • out: parametr se z klíčové slovo bude zacházeno jako výstupní parametr

ale to je opravdu nejzákladnější odpověď můžete dát, protože je to trochu složitější, než je zde uvedeno

Odpovězeno 16/08/2008 v 10:21
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more