Różnica między parametrami ref i out in.NET [duplikat]

To pytanie ma już odpowiedź tutaj:

Jaka jest różnica między parametrami ref i out W. NET? jakie są sytuacje, w których jeden może być bardziej użyteczny niż drugi? Jaki byłby fragment kodu, w którym jeden może być użyty, a drugi nie?

 389
Author: Mike Cole, 2008-09-25

18 answers

Są prawie takie same - jedyna różnica polega na tym, że zmienna, którą przekazujesz jako parametr out, nie musi być inicjalizowana, ale przekazując ją jako parametr ref, musi być ustawiona na coś.

int x;
Foo(out x); // OK

int y;
Foo(ref y); // Error: y should be initialized before calling the method

Ref parametry są dla danych, które mogą zostać zmodyfikowane, out parametry są dla danych, które są dodatkowym wyjściem dla funkcji (np int.TryParse), które już używają wartości zwracanej dla czegoś.

 476
Author: Khoth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 10:24:15

Dlaczego C# ma zarówno ' ref 'jak i'out'?

Wywołujący metodę, która pobiera parametr out, nie jest zobowiązany do przypisania zmiennej przekazanej jako parametr out przed wywołaniem; jednak wywołanie jest wymagane do przypisania parametru out przed powrotem.

W kontraście parametry ref są uważane za początkowo przypisane przez wywołującego. W związku z tym callee nie jest wymagane przypisanie do parametru ref przed użyciem. Parametry Ref są przekazywane zarówno do, jak i na zewnątrz metody.

Więc out oznacza wyjście, podczas gdy {[1] } jest dla wejścia i wyjścia.

Odpowiadają one ściśle parametrom [out] i [in,out] interfejsów COM, zaletą parametrów out jest to, że wywołujący nie muszą przekazywać wcześniej przydzielonego obiektu w przypadkach, gdy nie jest on potrzebny przez wywołaną metodę-pozwala to uniknąć zarówno kosztów alokacji, jak i wszelkich kosztów, które mogą być związane z marshalingiem (bardziej prawdopodobne w przypadku COM, ale nie rzadkością w. NET).

 124
Author: Derek Park,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-24 13:48:08

ref oraz out pozwalają wywołanej metodzie na modyfikację parametru. Różnica między nimi polega na tym, co się dzieje zanim wykonasz telefon.

  • ref oznacza, że parametr ma na sobie wartość przed przejściem do funkcji. Wywołana funkcja może odczytać lub zmienić wartość w dowolnym momencie. parametr wchodzi, a następnie wychodzi

  • out oznacza, że parametr nie ma oficjalnej wartości przed przejściem do funkcji. Wywołana funkcja musi ją zainicjować. parametr wychodzi tylko

Oto Mój ulubiony sposób na to: ref jest przekazywanie zmiennych przez odniesienie. {[2] } jest zadeklarowaniem drugorzędnej wartości zwracanej dla funkcji. To tak jakbyś mógł to napisać:

// This is not C#
public (bool, string) GetWebThing(string name, ref Buffer paramBuffer);

// This is C#
public bool GetWebThing(string name, ref Buffer paramBuffer, out string actualUrl);
Oto bardziej szczegółowa lista efektów każdej alternatywy:]}

Przed wywołaniem metody:

ref: wywołujący musi ustawić wartość parametru przed przekazanie go do wywołanej metody.

out: metoda wywołująca nie jest wymagana do ustawienia wartości argumentu przed wywołaniem metody. Najprawdopodobniej nie powinieneś. w rzeczywistości, każda aktualna wartość jest odrzucana.

Podczas rozmowy:

ref: wywołana metoda może odczytać argument w dowolnym momencie.

out: wywołana metoda musi zainicjować parametr przed jego odczytaniem.

Remoted calls:

ref: aktualna wartość jest ustawiana na zdalne połączenie. Dodatkowy koszt wykonania.

out: nic nie jest przekazywane do połączenia zdalnego. Szybciej.

Technicznie rzecz biorąc, można użyć zawsze ref zamiast out, ale out pozwala być bardziej precyzyjnym co do znaczenia argumentu, a czasami może być o wiele bardziej wydajny.

 82
Author: Euro Micelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 20:51:19

Przykład dla OUT: zmienna pobiera wartość zainicjalizowaną po przejściu do metody. Później ta sama wartość jest zwracana do głównej metody.

namespace outreftry
{
    class outref
    {
        static void Main(string[] args)
        {
            yyy a = new yyy(); ;

            // u can try giving int i=100 but is useless as that value is not passed into
            // the method. Only variable goes into the method and gets changed its
            // value and comes out. 
            int i; 

            a.abc(out i);

            System.Console.WriteLine(i);
        }
    }
    class yyy
    {

        public void abc(out int i)
        {

            i = 10;

        }

    }
}

Wyjście:

10

===============================================

Przykład dla zmiennej Ref : należy zainicjować przed przejściem do metody. Później ta sama wartość lub zmodyfikowana wartość zostanie zwrócona do głównej metody.

namespace outreftry
{
    class outref
    {
        static void Main(string[] args)
        {
            yyy a = new yyy(); ;

            int i = 0;

            a.abc(ref i);

            System.Console.WriteLine(i);
        }
    }
    class yyy
    {

        public void abc(ref int i)
        {
            System.Console.WriteLine(i);
            i = 10;

        }

    }
}

Wyjście:

    0
    10

=================================

Nadzieja teraz czysto.

 15
Author: Nawaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-24 06:22:37
  • zmienna ref musi zostać zainicjowana przed jej przekazaniem.
  • zmienna out musi być ustawiona w implementacji funkcji
  • out parametry mogą być traktowane jako dodatkowe zmienne zwrotne (nie wejściowe)
  • ref parametry mogą być traktowane jako zmienne wejściowe i wyjściowe.
 9
Author: Brian R. Bondy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-08 20:00:51

Parametry Ref i Out:

Parametry out i ref są używane do zwracania wartości w tej samej zmiennej, którą przekazujesz jako argument metody. Oba te parametry są bardzo przydatne, gdy metoda musi zwrócić więcej niż jedną wartość.

Musisz przypisać wartość do out parametru w ciele metody calee, w przeciwnym razie metoda nie zostanie skompilowana.


Parametr Ref: musi zostać zainicjowany przed przekazaniem do metody. Na ref słowo kluczowe w parametrze metody powoduje, że metoda odnosi się do tej samej zmiennej, która została przekazana jako parametr wejściowy dla tej samej metody. Jeśli dokonasz jakichkolwiek zmian w zmiennej, zostaną one odzwierciedlone w zmiennej.

int sampleData = 0; 
sampleMethod(ref sampleData);

Ex parametru Ref

public static void Main() 
{ 
 int i = 3; // Variable need to be initialized 
 sampleMethod(ref i );  
}

public static void sampleMethod(ref int sampleData) 
{ 
 sampleData++; 
} 

Out parametr: nie jest konieczne inicjowanie przed przekazaniem do metody. Parametr out może być użyty do zwrócenia wartości w tej samej zmiennej przekazywane jako parametr metody. Wszelkie zmiany wprowadzone do parametru zostaną odzwierciedlone w zmiennej.

 int sampleData; 
 sampleMethod(out sampleData);

Ex z parametru Out

public static void Main() 
{ 
 int i, j; // Variable need not be initialized 
 sampleMethod(out i, out j); 
} 
public static int sampleMethod(out int sampleData1, out int sampleData2) 
{ 
 sampleData1 = 10; 
 sampleData2 = 20; 
 return 0; 
} 

 9
Author: Krishna Thota,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-16 12:23:17

Out:

W C# metoda może zwracać tylko jedną wartość. Jeśli chcesz zwrócić więcej niż jedną wartość, możesz użyć słowa kluczowego out. Modyfikator out powraca jako return-by-reference. Najprostszą odpowiedzią jest to, że słowo kluczowe " out " jest używane do uzyskania wartości z metody.

  • nie musisz inicjalizować wartości w funkcji wywołującej.
  • musisz przypisać wartość w wywołanej funkcji, w przeciwnym razie kompilator zgłosi błąd.

Ref:

W C#, gdy przekazujesz typ wartości, taki jak int, float, double itp. jako argument do parametru metody jest przekazywana przez wartość. Dlatego, jeśli zmodyfikujesz wartość parametru, nie wpłynie to na argument w wywołaniu metody. Ale jeśli zaznaczysz parametr słowem kluczowym "ref", będzie on odzwierciedlał w rzeczywistej zmiennej.

  • musisz zainicjalizować zmienną przed wywołaniem funkcji.
  • nie jest obowiązkowe przypisywanie żadnej wartości do ref parametr w metodzie. Jeśli nie zmienisz wartości, jaka jest potrzeba, aby oznaczyć ją jako "ref"?
 6
Author: Nazmul Hasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 16:54:40

Parametry Ref nie muszą być ustawiane w funkcji, podczas gdy parametry out muszą być powiązane z wartością przed zakończeniem funkcji. Zmienne przekazywane jako nie mogą być również przekazywane do funkcji bez inicjalizacji.

 4
Author: Patrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 18:59:18

out określa, że parametr jest parametrem wyjściowym, tzn. nie ma wartości, dopóki nie zostanie jawnie ustawiony przez metodę.

ref Określa, że wartość jest referencją, która ma wartość i której wartość można zmienić wewnątrz metody.

 4
Author: Alan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-08 20:01:45

out parametry są inicjowane wywołaną metodą, ref parametry są inicjowane przed wywołaniem metody. Dlatego parametry {[0] } są używane, gdy musisz tylko uzyskać wtórną wartość zwracaną, parametry ref są używane do uzyskania wartości i potencjalnie zwracają zmianę tej wartości (wtórnie do głównej wartości zwracanej).

 1
Author: bdukes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 19:00:59

Słowo kluczowe ref jest używane do przekazywania wartości przez odniesienie. (Nie wyklucza to, że przekazywane wartości są typami wartości lub typami referencji). Parametry wyjściowe określone słowem kluczowym out służą do zwracania wartości z metody.

Jedną z kluczowych różnic w kodzie jest to, że musisz ustawić wartość parametru wyjściowego w metodzie. Tak nie jest w przypadku parametrów ref.

Po więcej szczegółów zajrzyj do http://www.blackwasp.co.uk/CSharpMethodParameters.aspx

 1
Author: BlackWasp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 19:02:16

Parametr out jest parametrem ref z dodanym specjalnym atrybutem Out(). Jeśli parametr do metody C# jest zadeklarowany jako out, kompilator będzie wymagał, aby parametr został napisany przed jego odczytaniem i przed powrotem metody. Jeśli C# wywoła metodę, której parametr zawiera atrybut Out(), kompilator, w celu podjęcia decyzji o zgłoszeniu błędów "undefined variable", będzie udawał, że zmienna została napisana bezpośrednio przed wywołaniem metody. Zauważ, że ponieważ inne języki. Net nie przypisują tego samego znaczenia atrybutowi Out(), możliwe jest, że wywołanie procedury z parametrem out pozostawi daną zmienną bez zmian. Jeśli zmienna jest używana jako parametr out przed jej definitywnym przypisaniem, kompilator C# wygeneruje kod, aby upewnić się, że zostanie wyczyszczona w pewnym momencie przed jej użyciem, ale jeśli taka zmienna opuści i ponownie wejdzie w zakres, nie ma gwarancji, że zostanie ponownie wyczyszczona.

 1
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-01 23:41:14

Ref prawdopodobnie zadławi się null, ponieważ prawdopodobnie oczekuje modyfikacji istniejącego obiektu. out oczekuje null, ponieważ zwraca nowy obiekt.

 0
Author: Joel Coehoorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 18:58:51

Out i ref są dokładnie takie same, z tym wyjątkiem, że zmienne out nie muszą być inicjalizowane przed wysłaniem ich do otchłani. Nie jestem aż tak bystry, ja to z biblioteki MSDN wywaliłem:).

Aby być bardziej wyraźnym o ich użyciu, znaczenie modyfikatora jest takie, że jeśli zmienisz odniesienie do tej zmiennej w kodzie, out i ref spowoduje, że zmienna wywołująca zmieni również odniesienie. W poniższym kodzie zmienna ceo będzie nawiązaniem do newGuy po powrocie z rozmowy do doStuff. Gdyby nie ref (lub out) Referencja nie zostałaby zmieniona.

private void newEmployee()
{
    Person ceo = Person.FindCEO();
    doStuff(ref ceo);
}

private void doStuff(ref Person employee)
{
    Person newGuy = new Person();
    employee = newGuy;
}
 0
Author: Jacob Proffitt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 19:05:18

To out I ref Paramerter w C# ma kilka dobrych przykładów.

Podstawowa różnica polega na tym, że parametry out nie muszą być inicjalizowane, gdy są przekazywane, podczas gdy parametry ref tak.

 0
Author: casademora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-20 16:21:23

Gdy parametr out jest zadeklarowany w deklaracji metody, ciało metody powinno przypisać wartość zmiennej out przed zwróceniem. Zatem zadaniem wywołanej metody jest przypisanie wartości do parametru out przed jego powrotem.

Gdy parametr ref jest zadeklarowany w metodzie, argument przekazywany podczas wywoływania metody powinien mieć przypisaną wartość. Więc zadaniem wywołującego jest przypisanie wartości argumentu ref przed wywołaniem metody.

 0
Author: Ranganatha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 16:17:49

Są subtelnie różne.

Parametr out nie musi być inicjowany przez callee przed przekazaniem do metody. Dlatego każda metoda z parametrem out

  • nie można odczytać parametru przed przypisaniem mu wartości
  • musi przypisać jej wartość przed zwróceniem

Jest to używane dla metody, która musi nadpisać swój argument niezależnie od jego poprzedniej wartości.


A ref parametr musi być zainicjowany przez callee przed przekazaniem go do metody. Dlatego każda metoda z parametrem ref

  • może sprawdzić wartość przed przypisaniem jej
  • może zwrócić oryginalną wartość, nietkniętą

Jest to używane do metody, która musi (np.) sprawdzić jej wartość i ją zweryfikować lub znormalizować.

 0
Author: jpaugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-01 15:45:25

Out ma nową składnię bardziej succint w C # 7 https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#more-expression-bodied-members a jeszcze bardziej ekscytujące są ulepszenia tuple C # 7, które są bardziej eleganckim wyborem niż używanie ref i out IMHO.

 0
Author: Marc Ziss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-17 16:11:50