Szkolenie
Moduł
Tworzenie metod języka C#, które zwracają wartości - Training
W tym module omówiono słowo kluczowe return i zwracane wartości z metod.
Ta przeglądarka nie jest już obsługiwana.
Przejdź na przeglądarkę Microsoft Edge, aby korzystać z najnowszych funkcji, aktualizacji zabezpieczeń i pomocy technicznej.
Metoda to blok kodu, który zawiera serię instrukcji. Program powoduje wykonanie instrukcji przez wywołanie metody i określenie wszelkich wymaganych argumentów metody. W języku C# każda wykonywana instrukcja jest wykonywana w kontekście metody.
Uwaga
W tym temacie omówiono metody nazwane. Aby uzyskać informacje o funkcjach anonimowych, zobacz Wyrażenia lambda.
Metody są deklarowane w obiekcie class
, record
lub struct
przez określenie:
public
lub private
. Wartość domyślna to private
.abstract
lub sealed
.void
jeśli metoda nie ma żadnej.Te części razem tworzą sygnaturę metody.
Ważne
Zwracany typ metody nie jest częścią podpisu metody do celów przeciążenia metody. Jednak jest ona częścią podpisu metody podczas określania zgodności między delegatem a metodą, do której wskazuje.
W poniższym przykładzie zdefiniowano klasę o nazwie Motorcycle
zawierającą pięć metod:
namespace MotorCycleExample
{
abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }
// Only derived classes can call this.
protected void AddGas(int gallons) { /* Method statements here */ }
// Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }
// Derived classes can override the base class implementation.
public virtual int Drive(TimeSpan time, int speed) { /* Method statements here */ return 0; }
// Derived classes must implement this.
public abstract double GetTopSpeed();
}
Klasa Motorcycle
zawiera przeciążony metodę . Drive
Dwie metody mają taką samą nazwę, ale są rozróżniane przez ich typy parametrów.
Metody mogą być wystąpieniem lub statycznym. Należy utworzyć wystąpienie obiektu, aby wywołać metodę wystąpienia w tym wystąpieniu; metoda wystąpienia działa na tym wystąpieniu i jego danych. Metoda statyczna jest wywoływana przez odwoływanie się do nazwy typu, do którego należy metoda; metody statyczne nie działają na danych wystąpienia. Próba wywołania metody statycznej za pomocą wystąpienia obiektu generuje błąd kompilatora.
Wywoływanie metody przypomina uzyskiwanie dostępu do pola. Po nazwie obiektu (jeśli wywołujesz metodę wystąpienia) lub nazwie typu (jeśli wywołujesz metodę static
), dodaj kropkę, nazwę metody i nawiasy. Argumenty są wymienione w nawiasach i są rozdzielane przecinkami.
Definicja metody określa nazwy i typy wszystkich wymaganych parametrów. Gdy obiekt wywołujący wywołuje metodę, udostępnia konkretne wartości, nazywane argumentami, dla każdego parametru. Argumenty muszą być zgodne z typem parametru, ale nazwa argumentu, jeśli jest używana w kodzie wywołującym, nie musi być taka sama jak parametr o nazwie zdefiniowanej w metodzie. W poniższym przykładzie Square
metoda zawiera jeden parametr typu int
o nazwie i. Pierwsze wywołanie metody przekazuje metodę Square
zmienną typu int
o nazwie num; drugą, stałą liczbową, a trzecią wyrażeniem.
public static class SquareExample
{
public static void Main()
{
// Call with an int variable.
int num = 4;
int productA = Square(num);
// Call with an integer literal.
int productB = Square(12);
// Call with an expression that evaluates to int.
int productC = Square(productA * 3);
}
static int Square(int i)
{
// Store input argument in a local variable.
int input = i;
return input * input;
}
}
Najbardziej typowa forma wywołania metody używa argumentów pozycyjnych; dostarcza argumenty w tej samej kolejności co parametry metody. Metody Motorcycle
klasy można zatem wywołać tak, jak w poniższym przykładzie. Wywołanie Drive
metody, na przykład, zawiera dwa argumenty, które odpowiadają dwóm parametrom w składni metody. Pierwszy staje się wartością parametru miles
. Drugi staje się wartością parametru speed
.
class TestMotorcycle : Motorcycle
{
public override double GetTopSpeed() => 108.4;
static void Main()
{
var moto = new TestMotorcycle();
moto.StartEngine();
moto.AddGas(15);
_ = moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}
Podczas wywoływania metody można również użyć nazwanych argumentów zamiast argumentów pozycyjnych. W przypadku używania nazwanych argumentów należy określić nazwę parametru, po którym następuje dwukropek (":") i argument. Argumenty metody mogą być wyświetlane w dowolnej kolejności, o ile wszystkie wymagane argumenty są obecne. W poniższym przykładzie użyto nazwanych argumentów do wywołania TestMotorcycle.Drive
metody . W tym przykładzie nazwane argumenty są przekazywane w odwrotnej kolejności z listy parametrów metody.
namespace NamedMotorCycle;
class TestMotorcycle : Motorcycle
{
public override int Drive(int miles, int speed) =>
(int)Math.Round((double)miles / speed, 0);
public override double GetTopSpeed() => 108.4;
static void Main()
{
var moto = new TestMotorcycle();
moto.StartEngine();
moto.AddGas(15);
int travelTime = moto.Drive(miles: 170, speed: 60);
Console.WriteLine("Travel time: approx. {0} hours", travelTime);
}
}
// The example displays the following output:
// Travel time: approx. 3 hours
Metodę można wywołać przy użyciu argumentów pozycyjnych i argumentów nazwanych. Jednak argumenty pozycyjne mogą być zgodne tylko z nazwanych argumentów, gdy nazwane argumenty znajdują się we poprawnych pozycjach. Poniższy przykład wywołuje metodę TestMotorcycle.Drive
z poprzedniego przykładu przy użyciu jednego argumentu pozycyjnego i jednego nazwanego argumentu.
int travelTime = moto.Drive(170, speed: 55);
Oprócz składowych, które są jawnie zdefiniowane w typie, typ dziedziczy elementy członkowskie zdefiniowane w klasach bazowych. Ponieważ wszystkie typy w zarządzanym systemie typów dziedziczą bezpośrednio lub pośrednio z Object klasy, wszystkie typy dziedziczą jego składowe, takie jak Equals(Object), GetType()i ToString(). W poniższym przykładzie zdefiniowano klasę , tworzy Person
wystąpienia dwóch Person
obiektów i wywołuje metodę Person.Equals
w celu określenia, czy dwa obiekty są równe. Metoda Equals
nie jest jednak zdefiniowana w Person
klasie ; jest dziedziczona z Objectklasy .
public class Person
{
public string FirstName = default!;
}
public static class ClassTypeExample
{
public static void Main()
{
Person p1 = new() { FirstName = "John" };
Person p2 = new() { FirstName = "John" };
Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
}
}
// The example displays the following output:
// p1 = p2: False
Typy mogą zastępować dziedziczone elementy członkowskie przy użyciu słowa kluczowego override
i dostarczać implementację dla metody przesłoniętej. Sygnatura metody musi być taka sama jak metoda przesłonięć. Poniższy przykład jest podobny do poprzedniego, z tą różnicą, że zastępuje metodę Equals(Object) . (Zastępuje również metodę GetHashCode() , ponieważ obie metody mają na celu zapewnienie spójnych wyników).
namespace methods;
public class Person
{
public string FirstName = default!;
public override bool Equals(object? obj) =>
obj is Person p2 &&
FirstName.Equals(p2.FirstName);
public override int GetHashCode() => FirstName.GetHashCode();
}
public static class Example
{
public static void Main()
{
Person p1 = new() { FirstName = "John" };
Person p2 = new() { FirstName = "John" };
Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
}
}
// The example displays the following output:
// p1 = p2: True
Typy w języku C# to typy wartości lub typy referencyjne. Aby uzyskać listę wbudowanych typów wartości, zobacz Typy. Domyślnie zarówno typy wartości, jak i typy referencyjne są przekazywane przez wartość do metody.
Gdy typ wartości jest przekazywany do metody według wartości, kopia obiektu zamiast samego obiektu jest przekazywana do metody . W związku z tym zmiany obiektu w wywoływanej metodzie nie mają wpływu na oryginalny obiekt, gdy kontrolka powraca do obiektu wywołującego.
Poniższy przykład przekazuje typ wartości do metody według wartości, a wywołana metoda próbuje zmienić wartość typu wartości. Definiuje zmienną typu int
, która jest typem wartości, inicjuje jej wartość do 20 i przekazuje ją do metody o nazwie ModifyValue
, która zmienia wartość zmiennej na 30. Gdy jednak metoda zwróci wartość zmiennej, pozostaje niezmieniona.
public static class ByValueExample
{
public static void Main()
{
var value = 20;
Console.WriteLine("In Main, value = {0}", value);
ModifyValue(value);
Console.WriteLine("Back in Main, value = {0}", value);
}
static void ModifyValue(int i)
{
i = 30;
Console.WriteLine("In ModifyValue, parameter value = {0}", i);
return;
}
}
// The example displays the following output:
// In Main, value = 20
// In ModifyValue, parameter value = 30
// Back in Main, value = 20
Gdy obiekt typu odwołania jest przekazywany do metody według wartości, odwołanie do obiektu jest przekazywane przez wartość. Oznacza to, że metoda nie odbiera samego obiektu, ale argument wskazujący lokalizację obiektu. Jeśli zmienisz element członkowski obiektu przy użyciu tego odwołania, zmiana zostanie odzwierciedlona w obiekcie, gdy kontrolka powróci do metody wywołującej. Jednak zastąpienie obiektu przekazanego do metody nie ma wpływu na oryginalny obiekt, gdy kontrolka powróci do obiektu wywołującego.
W poniższym przykładzie zdefiniowano klasę (która jest typem odwołania) o nazwie SampleRefType
. Tworzy wystąpienie SampleRefType
obiektu, przypisuje 44 do pola value
i przekazuje obiekt do ModifyObject
metody . W tym przykładzie zasadniczo jest to samo, co w poprzednim przykładzie — przekazuje argument według wartości do metody. Ale ponieważ jest używany typ odwołania, wynik jest inny. Modyfikacja wprowadzona w ModifyObject
obj.value
polu zmienia value
również pole argumentu , rt
w Main
metodzie na 33, jak pokazano w danych wyjściowych z przykładu.
public class SampleRefType
{
public int value;
}
public static class ByRefTypeExample
{
public static void Main()
{
var rt = new SampleRefType { value = 44 };
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj) => obj.value = 33;
}
Parametr jest przekazywany przez odwołanie, gdy chcesz zmienić wartość argumentu w metodzie i chcesz odzwierciedlić tę zmianę, gdy kontrolka powróci do metody wywołującej. Aby przekazać parametr za pomocą odwołania, należy użyć słowa kluczowego ref
lub out
. Możesz również przekazać wartość przy użyciu odwołania, aby uniknąć kopiowania, ale nadal zapobiegać modyfikacjom przy użyciu słowa kluczowego in
.
Poniższy przykład jest identyczny z poprzednim, z tą różnicą, że wartość jest przekazywana przez odwołanie do ModifyValue
metody . Gdy wartość parametru zostanie zmodyfikowana w metodzie ModifyValue
, zmiana wartości zostanie odzwierciedlona, gdy kontrolka powróci do obiektu wywołującego.
public static class ByRefExample
{
public static void Main()
{
var value = 20;
Console.WriteLine("In Main, value = {0}", value);
ModifyValue(ref value);
Console.WriteLine("Back in Main, value = {0}", value);
}
private static void ModifyValue(ref int i)
{
i = 30;
Console.WriteLine("In ModifyValue, parameter value = {0}", i);
return;
}
}
// The example displays the following output:
// In Main, value = 20
// In ModifyValue, parameter value = 30
// Back in Main, value = 30
Typowy wzorzec używany przez parametry ref obejmuje zamianę wartości zmiennych. Przekazujesz dwie zmienne do metody według odwołania, a metoda zamienia ich zawartość. Poniższy przykład zamienia wartości całkowite.
public static class RefSwapExample
{
static void Main()
{
int i = 2, j = 3;
Console.WriteLine("i = {0} j = {1}", i, j);
Swap(ref i, ref j);
Console.WriteLine("i = {0} j = {1}", i, j);
}
static void Swap(ref int x, ref int y) =>
(y, x) = (x, y);
}
// The example displays the following output:
// i = 2 j = 3
// i = 3 j = 2
Przekazanie parametru typu odwołania umożliwia zmianę wartości samego odwołania, a nie wartości poszczególnych elementów lub pól.
Czasami wymaganie, aby określić dokładną liczbę argumentów dla metody, jest restrykcyjne. Używając słowa kluczowego wskazującego params
, że parametr jest kolekcją parametrów, można wywołać metodę przy użyciu zmiennej liczby argumentów. Parametr oznaczony params
słowem kluczowym musi być typem kolekcji i musi być ostatnim parametrem na liście parametrów metody.
Obiekt wywołujący może następnie wywołać metodę na jeden z czterech sposobów dla parametru params
:
null
.W poniższym przykładzie zdefiniowano metodę o nazwie GetVowels
, która zwraca wszystkie vowels z kolekcji parametrów. Metoda Main
ilustruje wszystkie cztery sposoby wywoływania metody. Obiekty wywołujące nie są wymagane do podania żadnych argumentów dla parametrów, które zawierają params
modyfikator. W takim przypadku parametr jest pustą kolekcją.
static class ParamsExample
{
static void Main()
{
string fromArray = GetVowels(["apple", "banana", "pear"]);
Console.WriteLine($"Vowels from collection expression: '{fromArray}'");
string fromMultipleArguments = GetVowels("apple", "banana", "pear");
Console.WriteLine($"Vowels from multiple arguments: '{fromMultipleArguments}'");
string fromNull = GetVowels(null);
Console.WriteLine($"Vowels from null: '{fromNull}'");
string fromNoValue = GetVowels();
Console.WriteLine($"Vowels from no value: '{fromNoValue}'");
}
static string GetVowels(params IEnumerable<string>? input)
{
if (input == null || !input.Any())
{
return string.Empty;
}
char[] vowels = ['A', 'E', 'I', 'O', 'U'];
return string.Concat(
input.SelectMany(
word => word.Where(letter => vowels.Contains(char.ToUpper(letter)))));
}
}
// The example displays the following output:
// Vowels from array: 'aeaaaea'
// Vowels from multiple arguments: 'aeaaaea'
// Vowels from null: ''
// Vowels from no value: ''
Przed językiem C# 13 params
modyfikator może być używany tylko z jednowymiarową tablicą.
Definicja metody może określić, że jego parametry są wymagane lub że są opcjonalne. Domyślnie wymagane są parametry. Parametry opcjonalne są określane przez uwzględnienie wartości domyślnej parametru w definicji metody. Gdy metoda jest wywoływana, jeśli dla opcjonalnego parametru nie zostanie podany żaden argument, zamiast tego zostanie użyta wartość domyślna.
Wartość domyślna parametru jest przypisywana z jednym z następujących rodzajów wyrażeń:
Stała, taka jak ciąg literału lub liczba.
Wyrażenie formularza default(SomeType)
, w którym SomeType
może być typem wartości lub typem odwołania. Jeśli jest to typ odwołania, jest on w rzeczywistości taki sam jak określenie null
elementu . Można użyć default
literału, ponieważ kompilator może wywnioskować typ z deklaracji parametru.
Wyrażenie formularza new ValType()
, gdzie ValType
jest typem wartości. To wyrażenie wywołuje niejawny konstruktor bez parametrów typu wartości, który nie jest rzeczywistym elementem członkowskim typu.
Uwaga
Gdy wyrażenie formularza new ValType()
wywołuje jawnie zdefiniowany konstruktor bez parametrów typu wartości, kompilator generuje błąd, ponieważ domyślna wartość parametru musi być stałą czasu kompilacji.
default(ValType)
Użyj wyrażenia lub literału, aby podać domyślną wartość parametrudefault
. Aby uzyskać więcej informacji na temat konstruktorów bez parametrów, zobacz sekcję Inicjowanie struktury i wartości domyślne w artykule Typy struktury.
Jeśli metoda zawiera zarówno wymagane, jak i opcjonalne parametry, parametry opcjonalne są definiowane na końcu listy parametrów, po wszystkich wymaganych parametrach.
W poniższym przykładzie zdefiniowano metodę , ExampleMethod
która ma jeden wymagany i dwa parametry opcjonalne.
public class Options
{
public void ExampleMethod(int required, int optionalInt = default,
string? description = default)
{
var msg = $"{description ?? "N/A"}: {required} + {optionalInt} = {required + optionalInt}";
Console.WriteLine(msg);
}
}
Obiekt wywołujący musi podać argument dla wszystkich parametrów opcjonalnych do ostatniego opcjonalnego parametru, dla którego podano argument. W metodzie ExampleMethod
, na przykład jeśli obiekt wywołujący dostarcza argument dla parametru description
, musi również podać jeden dla parametru optionalInt
.
opt.ExampleMethod(2, 2, "Addition of 2 and 2");
jest prawidłowym wywołaniem metody; opt.ExampleMethod(2, , "Addition of 2 and 0");
Generuje błąd kompilatora "Brak argumentu".
Jeśli metoda jest wywoływana przy użyciu nazwanych argumentów lub kombinacji argumentów pozycyjnych i nazwanych, obiekt wywołujący może pominąć wszelkie argumenty, które są zgodne z ostatnim argumentem pozycyjnym w wywołaniu metody.
Poniższy przykład wywołuje metodę ExampleMethod
trzy razy. Pierwsze dwie metody używają argumentów pozycyjnych. Pierwszy pomija oba opcjonalne argumenty, podczas gdy drugi pomija ostatni argument. Trzecie wywołanie metody dostarcza argument pozycyjny dla wymaganego parametru, ale używa nazwanego argumentu, aby podać wartość parametrowi description
podczas pomijania argumentu optionalInt
.
public static class OptionsExample
{
public static void Main()
{
var opt = new Options();
opt.ExampleMethod(10);
opt.ExampleMethod(10, 2);
opt.ExampleMethod(12, description: "Addition with zero:");
}
}
// The example displays the following output:
// N/A: 10 + 0 = 10
// N/A: 10 + 2 = 12
// Addition with zero:: 12 + 0 = 12
Użycie parametrów opcjonalnych wpływa na rozpoznawanie przeciążeń lub sposób, w jaki kompilator języka C# określa, które przeciążenie ma być wywoływane dla wywołania metody w następujący sposób:
Metody mogą zwracać wartość do elementu wywołującego. Jeśli zwracany typ (typ wymieniony przed nazwą metody) nie void
jest , metoda może zwrócić wartość przy użyciu słowa kluczowego return
. Instrukcja ze słowem kluczowym, po którym następuje zmienna, stała lub wyrażenie zgodne z return
typem zwracanym, zwraca tę wartość do wywołującego metodę. Metody z nievoidowym typem zwrotnym są wymagane do użycia return
słowa kluczowego w celu zwrócenia wartości. Słowo return
kluczowe zatrzymuje również wykonywanie metody .
Jeśli zwracany typ to void
, return
instrukcja bez wartości jest nadal przydatna do zatrzymania wykonywania metody. Bez słowa kluczowego return
metoda zatrzymuje wykonywanie, gdy osiągnie koniec bloku kodu.
Na przykład te dwie metody używają słowa kluczowego return
do zwracania liczb całkowitych:
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2) =>
number1 + number2;
public int SquareANumber(int number) =>
number * number;
}
Powyższe przykłady to składowe wyrażeń. Elementy członkowskie wyrażeń zwracają wartość zwracaną przez wyrażenie.
Możesz również zdefiniować metody za pomocą treści instrukcji i instrukcji return
:
class SimpleMathExtnsion
{
public int DivideTwoNumbers(int number1, int number2)
{
return number1 / number2;
}
}
Aby użyć wartości zwróconej z metody, metoda wywołująca może użyć wywołania metody w dowolnym miejscu, w jakim wartość tego samego typu byłaby wystarczająca. Możesz również przypisać wartość zwracaną do zmiennej. Na przykład następujące trzy przykłady kodu osiągają ten sam cel:
int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);
result = obj2.DivideTwoNumbers(6,2);
// The result is 3.
Console.WriteLine(result);
Czasami chcesz, aby metoda zwróciła więcej niż jedną wartość. Aby zwrócić wiele wartości, należy użyć typów krotki i literałów krotki. Typ krotki definiuje typy danych elementów krotki. Literały krotki zapewniają rzeczywiste wartości zwracanej krotki. W poniższym przykładzie (string, string, string, int)
definiuje typ krotki zwracany przez metodę GetPersonalInfo
. Wyrażenie (per.FirstName, per.MiddleName, per.LastName, per.Age)
jest literałem krotki; metoda zwraca pierwszą, środkową i rodzinną nazwę wraz z wiekiem PersonInfo
obiektu.
public (string, string, string, int) GetPersonalInfo(string id)
{
PersonInfo per = PersonInfo.RetrieveInfoById(id);
return (per.FirstName, per.MiddleName, per.LastName, per.Age);
}
Obiekt wywołujący może następnie korzystać z zwróconej krotki przy użyciu następującego kodu:
var person = GetPersonalInfo("111111111");
Console.WriteLine($"{person.Item1} {person.Item3}: age = {person.Item4}");
Nazwy można również przypisać do elementów krotki w definicji typu krotki. W poniższym przykładzie przedstawiono alternatywną wersję GetPersonalInfo
metody, która używa nazwanych elementów:
public (string FName, string MName, string LName, int Age) GetPersonalInfo(string id)
{
PersonInfo per = PersonInfo.RetrieveInfoById(id);
return (per.FirstName, per.MiddleName, per.LastName, per.Age);
}
Poprzednie wywołanie GetPersonalInfo
metody można następnie zmodyfikować w następujący sposób:
var person = GetPersonalInfo("111111111");
Console.WriteLine($"{person.FName} {person.LName}: age = {person.Age}");
Jeśli metoda przyjmuje tablicę jako parametr i modyfikuje wartość poszczególnych elementów, nie jest konieczne, aby metoda zwróciła tablicę. Język C# przekazuje wszystkie typy odwołań według wartości, a wartość odwołania do tablicy jest wskaźnikiem do tablicy. W poniższym przykładzie zmiany zawartości values
tablicy wprowadzonej w DoubleValues
metodzie można zaobserwować za pomocą dowolnego kodu, który zawiera odwołanie do tablicy.
public static class ArrayValueExample
{
static void Main()
{
int[] values = [2, 4, 6, 8];
DoubleValues(values);
foreach (var value in values)
{
Console.Write("{0} ", value);
}
}
public static void DoubleValues(int[] arr)
{
for (var ctr = 0; ctr <= arr.GetUpperBound(0); ctr++)
{
arr[ctr] *= 2;
}
}
}
// The example displays the following output:
// 4 8 12 16
Zazwyczaj istnieją dwa sposoby dodawania metody do istniejącego typu:
Metody rozszerzeń umożliwiają "dodawanie" metody do istniejącego typu bez modyfikowania samego typu lub implementowania nowej metody w dziedziczonego typu. Metoda rozszerzenia nie musi również znajdować się w tym samym zestawie, co typ, który rozszerza. Metoda rozszerzenia jest wywoływana tak, jakby była zdefiniowaną składową typu.
Aby uzyskać więcej informacji, zobacz Metody rozszerzeń.
Za pomocą funkcji asynchronicznej można wywoływać metody asynchroniczne bez użycia jawnych wywołań zwrotnych lub ręcznego dzielenia kodu między wiele metod lub wyrażeń lambda.
Jeśli oznaczysz metodę za pomocą modyfikatora asynchronicznego , możesz użyć operatora await w metodzie . Gdy kontrolka await
osiągnie wyrażenie w metodzie asynchronicznej, kontrolka powróci do elementu wywołującego, jeśli oczekiwane zadanie nie zostanie ukończone, a postęp w metodzie ze await
słowem kluczowym zostanie zawieszony do momentu zakończenia oczekiwanego zadania. Po zakończeniu zadania wykonanie może być wznowione w metodzie .
Uwaga
Metoda asynchronizna powraca do obiektu wywołującego, gdy napotka pierwszy oczekiwany obiekt, który nie został jeszcze ukończony, lub zostanie zakończony na końcu metody asynchronicznej, w zależności od tego, co nastąpi wcześniej.
Metoda asynchronicznie zwykle ma zwracany typ Task<TResult>, Task, IAsyncEnumerable<T>lub void
. Zwracany void
typ jest używany głównie do definiowania procedur obsługi zdarzeń, w których wymagany jest zwracany void
typ. Nie można oczekiwać metody asynchronicznej, która zwraca void
wartość , a obiekt wywołujący metody zwracanej przez pustkę nie może przechwytywać wyjątków zgłaszanych przez metodę. Metoda asynchronizna może mieć dowolny typ zwracany podobny do zadania.
W poniższym przykładzie DelayAsync
jest to metoda asynchronizna, która zawiera instrukcję return zwracającą liczbę całkowitą. Ponieważ jest to metoda asynchronizna, jego deklaracja metody musi mieć typ zwracany Task<int>
. Ponieważ zwracany typ to Task<int>
, ocena await
wyrażenia w DoSomethingAsync
obiekcie generuje liczbę całkowitą, jak pokazano w poniższej int result = await delayTask
instrukcji.
class Program
{
static Task Main() => DoSomethingAsync();
static async Task DoSomethingAsync()
{
Task<int> delayTask = DelayAsync();
int result = await delayTask;
// The previous two statements may be combined into
// the following statement.
//int result = await DelayAsync();
Console.WriteLine($"Result: {result}");
}
static async Task<int> DelayAsync()
{
await Task.Delay(100);
return 5;
}
}
// Example output:
// Result: 5
Metoda asynchroniczny nie może zadeklarować żadnych parametrów w parametrach, ref ani out, ale może wywoływać metody, które mają takie parametry.
Aby uzyskać więcej informacji na temat metod asynchronicznych, zobacz Asynchroniczne programowanie za pomocą asynchronicznych typów asynchronicznych i await i Async zwracanych typów.
Często zdarza się, że definicje metod zwracają się natychmiast z wynikiem wyrażenia lub mają pojedynczą instrukcję jako treść metody. Istnieje skrót składniowy do definiowania takich metod przy użyciu metody =>
:
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);
Jeśli metoda zwraca void
metodę async lub jest metodą asynchroniową, treść metody musi być wyrażeniem instrukcji (takim samym jak w przypadku lambd). W przypadku właściwości i indeksatorów muszą być tylko do odczytu i nie należy używać słowa kluczowego get
dostępu.
Iterator wykonuje iterację niestandardową w kolekcji, taką jak lista lub tablica. Iterator używa instrukcji zwrotu wydajności, aby zwrócić każdy element jeden naraz.
yield return
Po osiągnięciu instrukcji bieżąca lokalizacja jest zapamiętowana, aby obiekt wywołujący mógł zażądać następnego elementu w sekwencji.
Zwracany typ iteratora może mieć IEnumerablewartość , , IEnumerable<T>IAsyncEnumerable<T>, IEnumeratorlub IEnumerator<T>.
Aby uzyskać więcej informacji, zobacz Iteratory.
Opinia o produkcie .NET
.NET to projekt typu open source. Wybierz link, aby przekazać opinię:
Szkolenie
Moduł
Tworzenie metod języka C#, które zwracają wartości - Training
W tym module omówiono słowo kluczowe return i zwracane wartości z metod.