2012-06-26 23 views
9

Tak więc jestem nowy w C# i mam trudności ze zrozumieniem out. A nie tylko coś powrocie z funkcjiParametry C# out vs zwraca

using System; 
class ReturnTest 
{ 
    static double CalculateArea() 
    { 
     double r=5; 
     double area = r * r * Math.PI; 
     return area; 
    } 

    static void Main() 
    { 
     double output = CalculateArea(); 
     Console.WriteLine("The area is {0:0.00}", output); 
    } 
} 

porównać do tego

using System; 
class ReturnTest 
{ 
    static void CalculateArea(out double r) 
    { 
     r=5; 
     r= r * r * Math.PI; 
    } 

    static void Main() 
    { 
     double radius; 
     CalculateArea(out radius); 
     Console.WriteLine("The area is {0:0.00}",radius); 
     Console.ReadLine(); 
    } 
} 

Pierwszy z nich to jak bym generalnie to zrobić. Czy istnieje powód, dla którego mogę chcieć użyć out zamiast tylko zwrotu? Rozumiem, że ref pozwala na dwukierunkową komunikację i że generalnie nie powinienem używać ref, chyba że funkcja coś robi ze zmienną, którą wysyłam.

Czy jest jednak różnica między instrukcjami out i return, jak pokazano powyżej? Czy jest jakaś przyczyna faworyzowania jednej lub drugiej?

+8

Przestudiuj 'Dictionary.TryGetValue' i' int.TryParse' i sprawdź, czy te przykłady objaśniają użyteczność 'out'. –

+3

'out' jest najczęściej używany, gdy musisz zwrócić wiele niepowiązanych wartości z metody. Jak również, jest często używany do symulacji wskaźników podczas interakcji z natywnym kodem za pośrednictwem COM lub p/invoke. – dlev

+1

Pamiętaj w C/C++ mamy wskaźniki. Po przekazaniu wskaźnika do funkcji można go zmodyfikować w funkcji, a wartość zmieni się także w funkcji wywołującej. na zewnątrz robi prawie to samo. – carny666

Odpowiedz

13

Dobrym wykorzystanie out zamiast return na wynik jest wzór Try, które można zobaczyć w niektórych interfejsów API, na przykład Int32.TryParse(...). W tym wzorze wartość zwracana jest używana do sygnalizowania sukcesu lub niepowodzenia operacji (w przeciwieństwie do wyjątku), a parametr out służy do zwracania rzeczywistego wyniku.

Jedną z zalet w odniesieniu do Int32.Parse jest szybkość, ponieważ unika się wyjątków. Niektóre cele zostały przedstawione w tej drugiej kwestii: Parsing Performance (If, TryParse, Try-Catch)

1

Gdy jedna zmienna jest niepokojąca, a zwrot jest OK. Ale co jeśli chcesz zwrócić więcej niż 1 wartości? Out pomaga w tym.

static void CalculateArea(out double r, out double Foo) 
{ 
    //Can return 2 values in terms of out variables. 
} 

static double CalculateArea(double r) 
{ 
    // Will return only one value. 
} 
2

Można mieć wiele z parametrów, więc jeśli trzeba zwracać wiele wartości, jest to nieco łatwiejsze niż tworzenie specjalnej klasy dla wartości zwracanych.

+0

Nie mogę uwierzyć, że nie zrobiłem Pomyśl o tym dzięki –

4

Tylko czas staram się używać out to kiedy muszę wiele rzeczy wróciłem z jednej metody. Out pozwala uniknąć zawijania wielu obiektów do klasy w celu ich zwrócenia. Sprawdź przykład na stronie Microsoft Out page.

8

Słowo kluczowe out jest najczęściej używane, gdy chcesz zwrócić więcej niż jedną wartość z metody, bez konieczności zawijania wartości w obiekcie.

Przykładem jest metoda Int32.TryParse, która ma zarówno wartość zwracaną (wartość logiczna reprezentująca powodzenie próby), jak i parametr out, który pobiera wartość, jeśli przetwarzanie zakończyło się pomyślnie.

Metoda może zwrócić obiekt zawierający zarówno wartość boolean, jak i liczbę całkowitą, ale będzie potrzebna do utworzenia obiektu na stercie, co zmniejszy wydajność tej metody.

+0

Zastanawiam się również o różnicy wydajności (jeśli jest). Pochodzenie ze środowiska C++ argumentuje, że kopiowanie obiektu po zwróceniu przez wartość jest droższe. Czy to również dotyczy C#? Mam na myśli, że jeśli skonstruujesz zupełnie nowy, masywny obiekt w ramach funkcji i zwrócisz go, czy zostanie on skopiowany do tego, do czego przypisujesz? W przeciwieństwie do tworzenia obiektu i zmiany go za pomocą słowa kluczowego out? Czy to nie ma znaczenia w C#? – Reasurria

+0

@Reasurria: Jeśli utworzysz obiekt i zwrócisz go, zwracane jest tylko odwołanie, obiekty nie są klonowane. Obiekty .NET są klonowane tylko wtedy, gdy je klonujesz, a przekazywanie obiektów dookoła nie tworzy nowych kopii. – Guffa

+0

Dzięki temu będę o tym pamiętać. – Reasurria