Číst v angličtině

Sdílet prostřednictvím


Metody v jazyce C#

Metoda je blok kódu, který obsahuje řadu příkazů. Program způsobí, že příkazy se spustí voláním metody a určením požadovaných argumentů metody. V jazyce C# se každá spuštěná instrukce provádí v kontextu metody.

Poznámka

Toto téma popisuje pojmenované metody. Informace o anonymních funkcích naleznete v tématu Výrazy lambda.

Podpisy metody

Metody jsou deklarovány v objektu class, recordnebo struct zadáním:

  • Volitelná úroveň přístupu, například public .private Výchozí hodnota je private.
  • Volitelné modifikátory, například abstract nebo sealed.
  • Vrácená hodnota nebo void pokud metoda nemá žádnou.
  • Název metody.
  • Všechny parametry metody. Parametry metody jsou uzavřeny v závorkách a jsou odděleny čárkami. Prázdné závorky označují, že metoda nevyžaduje žádné parametry.

Tyto části společně tvoří podpis metody.

Důležité

Návratový typ metody není součástí podpisu metody pro účely přetížení metody. Je však součástí podpisu metody při určování kompatibility mezi delegátem a metodou, na kterou odkazuje.

Následující příklad definuje třídu s názvem Motorcycle , která obsahuje pět 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();
    }

Třída Motorcycle obsahuje přetíženou metodu , Drive. Dva metody mají stejný název, ale rozlišují se podle jejich typů parametrů.

Vyvolání metody

Metody můžou být buď instance , nebo statické. Je nutné vytvořit instanci objektu pro vyvolání metody instance v této instanci; Metoda instance pracuje s danou instancí a jejími daty. Vyvoláte statickou metodu odkazováním na název typu, ke kterému metoda patří; statické metody nefungují s daty instance. Pokus o volání statické metody prostřednictvím instance objektu generuje chybu kompilátoru.

Volání metody se podobá přístupu k poli. Za název objektu (pokud voláte metodu instance) nebo název typu (pokud voláte metodu static ), přidejte tečku, název metody a závorky. Argumenty jsou uvedeny v závorkách a jsou oddělené čárkami.

Definice metody určuje názvy a typy požadovaných parametrů. Když volající vyvolá metodu, poskytuje konkrétní hodnoty označované jako argumenty pro každý parametr. Argumenty musí být kompatibilní s typem parametru, ale název argumentu, pokud se používá ve volajícím kódu, nemusí být stejný jako parametr definovaný v metodě. V následujícím příkladu Square metoda obsahuje jeden parametr typu int s názvem i. První volání metody předá metodu Square proměnnou typu int pojmenovaného čísla, druhou, číselnou konstantu a třetí výraz.

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;
    }
}

Nejběžnější forma vyvolání metody použila poziční argumenty; poskytuje argumenty ve stejném pořadí jako parametry metody. Metody Motorcycle třídy lze proto volat jako v následujícím příkladu. Drive Volání metody například obsahuje dva argumenty, které odpovídají dvěma parametrům v syntaxi metody. První se stane hodnotou parametru miles . Druhým se stane hodnota 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);
    }
}

Při vyvolání metody můžete také použít pojmenované argumenty místo pozičních argumentů . Při použití pojmenovaných argumentů zadáte název parametru následovaný dvojtečka (":") a argument. Argumenty metody mohou být zobrazeny v libovolném pořadí, pokud jsou přítomny všechny požadované argumenty. Následující příklad používá pojmenované argumenty k vyvolání TestMotorcycle.Drive metody. V tomto příkladu se pojmenované argumenty předávají v opačném pořadí ze seznamu parametrů 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

Metodu můžete vyvolat pomocí pozičních argumentů i pojmenovaných argumentů. Poziční argumenty však mohou následovat pouze v případě, že jsou pojmenované argumenty ve správných pozicích. Následující příklad vyvolá metodu z předchozího příkladu TestMotorcycle.Drive pomocí jednoho pozičního argumentu a jednoho pojmenovaného argumentu.

int travelTime = moto.Drive(170, speed: 55);

Zděděné a přepisované metody

Kromě členů, které jsou explicitně definovány v typu, typ dědí členy definované ve svých základních třídách. Vzhledem k tomu, že všechny typy v systému spravovaných typů dědí přímo nebo nepřímo ze Object třídy, všechny typy dědí své členy, například Equals(Object), GetType()a ToString(). Následující příklad definuje Person třídu, vytvoří instanci dvou Person objektů a volá metodu Person.Equals k určení, zda jsou tyto dva objekty stejné. Metoda Equals však není definována ve Person třídě; je zděděna z Object.

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 mohou přepsat zděděné členy pomocí klíčového override slova a poskytnout implementaci pro přepsánou metodu. Podpis metody musí být stejný jako přepsáná metoda. Následující příklad je podobný předchozímu, s tím rozdílem, že přepíše metodu Equals(Object) . (Přepíše také metodu GetHashCode() , protože tyto dvě metody mají poskytovat konzistentní výsledky.)

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

Předávání parametrů

Typy v jazyce C# jsou typy hodnot nebo odkazové typy. Seznam předdefinovaných typů hodnot najdete v tématu Typy. Ve výchozím nastavení se do metody předávají oba typy hodnot i odkazové typy.

Předávání parametrů podle hodnoty

Pokud je typ hodnoty předán metodě podle hodnoty, kopie objektu místo samotného objektu je předána metodě. Změny objektu v volané metodě proto nemají žádný vliv na původní objekt, když se ovládací prvek vrátí volajícímu.

Následující příklad předá typ hodnoty metodě podle hodnoty a zavolá se metoda pokusí změnit hodnotu typu hodnoty. Definuje proměnnou typu int, což je typ hodnoty, inicializuje jeho hodnotu na 20 a předá ji metodě s názvem ModifyValue , která změní hodnotu proměnné na 30. Když však metoda vrátí hodnotu proměnné, zůstane beze změny.

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

Pokud je objekt typu odkazu předán metodě podle hodnoty, je odkaz na objekt předán hodnotou. To znamená, že metoda přijímá nikoli samotný objekt, ale argument, který označuje umístění objektu. Pokud změníte člen objektu pomocí tohoto odkazu, změna se projeví v objektu při návratu ovládacího prvku do volající metody. Nahrazení objektu předaného metodě však nemá žádný vliv na původní objekt při návratu ovládacího prvku volajícímu.

Následující příklad definuje třídu (což je typ odkazu) s názvem SampleRefType. Vytvoří instanci objektu SampleRefType , přiřadí 44 k jeho value poli a předá objekt metodě ModifyObject . Tento příklad v podstatě dělá totéž jako předchozí příklad – předává argument podle hodnoty metodě. Vzhledem k tomu, že se používá typ odkazu, je výsledek jiný. Změny provedené v ModifyObject obj.value poli také změní value pole argumentu , rtv Main metodě na 33, jak ukazuje výstup z příkladu.

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;
}

Předávání parametrů odkazem

Parametr předáte odkazem, když chcete změnit hodnotu argumentu v metodě a chcete tuto změnu odrážet při návratu ovládacího prvku do volající metody. Pokud chcete předat parametr odkazem, použijte klíčové ref slovo nebo out parametr. Můžete také předat hodnotu odkazem, abyste se vyhnuli kopírování, ale přesto zabránit úpravám pomocí klíčového in slova.

Následující příklad je stejný jako předchozí s výjimkou hodnoty je předán odkazem na metodu ModifyValue . Pokud je hodnota parametru změněna v ModifyValue metodě, změna hodnoty se projeví, když se ovládací prvek vrátí volajícímu.

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

Běžný vzor, který používá parametry ref, zahrnuje prohození hodnot proměnných. Dvě proměnné předáte metodě odkazem a metoda prohodí jejich obsah. Následující příklad prohodí celočíselné hodnoty.


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

Předání parametru typu odkazu umožňuje změnit hodnotu samotného odkazu, nikoli hodnotu jednotlivých prvků nebo polí.

Kolekce parametrů

Někdy je požadavek, který zadáte přesný počet argumentů pro vaši metodu, omezující. Když použijete params klíčové slovo k označení, že parametr je kolekce parametrů, můžete metodu volat s proměnným počtem argumentů. Parametr označený klíčovým slovem params musí být typ kolekce a musí to být poslední parametr v seznamu parametrů metody.

Volající pak může metodu vyvolat jedním ze čtyř způsobů pro params parametr:

  • Předáním kolekce vhodného typu, která obsahuje požadovaný počet prvků. V příkladu se používá výraz kolekce, aby kompilátor vytvořil odpovídající typ kolekce.
  • Předáním čárkami odděleného seznamu jednotlivých argumentů příslušného typu metodě. Kompilátor vytvoří odpovídající typ kolekce.
  • nullPředáním .
  • Poskytnutím argumentu pro kolekci parametrů.

Následující příklad definuje metodu s názvem GetVowels , která vrátí všechny samohlásky z kolekce parametrů. Tato Main metoda znázorňuje všechny čtyři způsoby vyvolání metody. Volající nemusí zadávat žádné argumenty pro parametry, které obsahují params modifikátor. V takovém případě je parametr prázdnou kolekcí.

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: ''

Před jazykem C# 13 params lze modifikátor použít pouze s jednorozměrným polem.

Volitelné parametry a argumenty

Definice metody může určit, že jsou jeho parametry povinné nebo že jsou volitelné. Ve výchozím nastavení jsou parametry povinné. Volitelné parametry jsou určeny zahrnutím výchozí hodnoty parametru do definice metody. Pokud je volána metoda, pokud není zadán žádný argument pro volitelný parametr, použije se místo toho výchozí hodnota.

Výchozí hodnotu parametru přiřadíte jedním z následujících typů výrazů:

  • Konstanta, například literálový řetězec nebo číslo.

  • Výraz formuláře default(SomeType), kde SomeType může být typ hodnoty nebo odkazový typ. Pokud se jedná o typ odkazu, je v podstatě stejný jako určení null. Literál můžete použít default , protože kompilátor může odvodit typ z deklarace parametru.

  • Výraz formuláře new ValType(), kde ValType je typ hodnoty. Tento výraz vyvolá implicitní konstruktor bez parametrů typu hodnoty, který není skutečným členem typu.

    Poznámka

    Když výraz formuláře new ValType() v jazyce C# 10 a novější vyvolá explicitně definovaný konstruktor bez parametrů typu hodnoty, kompilátor vygeneruje chybu, protože výchozí hodnota parametru musí být konstanta kompilace. Pomocí výrazu default(ValType) nebo literálu default zadejte výchozí hodnotu parametru. Další informace o konstruktorech bez parametrů naleznete v části Inicializace struktury a výchozí hodnoty v článku Typy struktur.

Pokud metoda obsahuje povinné i volitelné parametry, volitelné parametry jsou definovány na konci seznamu parametrů po všech požadovaných parametrech.

Následující příklad definuje metodu, ExampleMethodkterá má jeden povinný a dva volitelné parametry.

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);
    }
}

Volající musí zadat argument pro všechny volitelné parametry až do posledního volitelného parametru, pro který je argument zadán. ExampleMethod V metodě, například pokud volající dodává argument pro description parametr, musí také zadat jeden pro optionalInt parametr. opt.ExampleMethod(2, 2, "Addition of 2 and 2"); je platné volání metody; opt.ExampleMethod(2, , "Addition of 2 and 0"); vygeneruje chybu kompilátoru Chybí argument.

Pokud je volána metoda pomocí pojmenovaných argumentů nebo kombinace pozičních a pojmenovaných argumentů, volající může vynechat všechny argumenty, které následují za posledním pozičním argumentem volání metody.

Následující příklad třikrát volá metodu ExampleMethod . První dvě volání metody používají poziční argumenty. První vynechá oba volitelné argumenty, zatímco druhý vynechá poslední argument. Třetí volání metody poskytuje poziční argument požadovaného parametru, ale používá pojmenovaný argument k zadání hodnoty description parametru při vynechání 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

Použití volitelných parametrů ovlivňuje rozlišení přetížení nebo způsob, jakým kompilátor jazyka C# určuje, které přetížení se má vyvolat pro volání metody následujícím způsobem:

  • Metoda, indexer nebo konstruktor je kandidátem na spuštění, pokud každý z jeho parametrů odpovídá názvu nebo pozici jednoho argumentu a tento argument lze převést na typ parametru.
  • Pokud se najde více než jeden kandidát, použijí se pravidla překladu přetížení pro upřednostňované převody na argumenty, které jsou explicitně zadány. Vynechané argumenty pro volitelné parametry se ignorují.
  • Pokud jsou dva kandidáti vyhodnoceni jako stejně dobrý, preference přejde k kandidátovi, který nemá volitelné parametry, pro které byly argumenty vynechány ve volání.

Vrácené hodnoty

Metody mohou vrátit hodnotu volajícímu. Pokud návratový typ (typ uvedený před názvem metody) není void, metoda může vrátit hodnotu pomocí klíčového return slova. Příkaz s return klíčovým slovem následovaným proměnnou, konstantou nebo výrazem, který odpovídá návratovém typu, vrátí danou hodnotu volajícímu metody. Metody s neoid návratovým typem jsou vyžadovány k použití klíčového return slova k vrácení hodnoty. Klíčové return slovo také zastaví provádění metody.

Pokud je voidnávratový typ , return příkaz bez hodnoty je stále užitečný k zastavení provádění metody. Bez klíčového return slova se metoda zastaví, když dosáhne konce bloku kódu.

Například tyto dvě metody používají return klíčové slovo k vrácení celých čísel:

class SimpleMath
{
    public int AddTwoNumbers(int number1, int number2) =>
        number1 + number2;

    public int SquareANumber(int number) =>
        number * number;
}

Výše uvedené příklady jsou výrazy bodyied members. Bodyied members return the value return by the expression.

Můžete také definovat metody s textem příkazu a příkazem return :

class SimpleMathExtnsion
{
    public int DivideTwoNumbers(int number1, int number2)
    {
        return number1 / number2;
    }
}

Pokud chcete použít hodnotu vrácenou metodou, může volající metoda použít samotné volání kdekoli, kde by byla dostatečná hodnota stejného typu. Návratovou hodnotu můžete také přiřadit proměnné. Například následující tři příklady kódu dosahují stejného cíle:

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);

Někdy chcete, aby vaše metoda vrátila více než jednu hodnotu. K vrácení více hodnot použijete typy řazené kolekce členů a literály řazené kolekce členů. Typ řazené kolekce členů definuje datové typy prvků řazené kolekce členů. Literály řazené kolekce členů poskytují skutečné hodnoty vrácené řazené kolekce členů. V následujícím příkladu (string, string, string, int) definuje typ řazené kolekce členů vrácený metodou GetPersonalInfo . Výraz (per.FirstName, per.MiddleName, per.LastName, per.Age) je literál řazené kolekce členů; metoda vrátí první, prostřední a rodinný název spolu s věkem objektu PersonInfo .

public (string, string, string, int) GetPersonalInfo(string id)
{
    PersonInfo per = PersonInfo.RetrieveInfoById(id);
    return (per.FirstName, per.MiddleName, per.LastName, per.Age);
}

Volající pak může vrácenou řazenou kolekci členů využívat pomocí následujícího kódu:

var person = GetPersonalInfo("111111111");
Console.WriteLine($"{person.Item1} {person.Item3}: age = {person.Item4}");

Názvy lze také přiřadit elementům řazené kolekce členů v definici typu řazené kolekce členů. Následující příklad ukazuje alternativní verzi GetPersonalInfo metody, která používá pojmenované elementy:

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);
}

Předchozí volání GetPersonalInfo metody lze upravit následujícím způsobem:

var person = GetPersonalInfo("111111111");
Console.WriteLine($"{person.FName} {person.LName}: age = {person.Age}");

Pokud metoda přebírá pole jako parametr a upravuje hodnotu jednotlivých prvků, není nutné, aby metoda vrátila pole. Jazyk C# předává všechny typy odkazů podle hodnoty a hodnota odkazu na matici je ukazatel na matici. V následujícím příkladu jsou změny obsahu values pole provedené v DoubleValues metodě pozorovatelné libovolným kódem, který má odkaz na pole.


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

Metody rozšíření

Obvykle existují dva způsoby, jak přidat metodu do existujícího typu:

  • Upravte zdrojový kód pro tento typ. Úprava zdroje vytvoří zásadní změnu, pokud přidáte také všechna soukromá datová pole pro podporu metody.
  • Definujte novou metodu v odvozené třídě. Metodu nelze tímto způsobem přidat pomocí dědičnosti pro jiné typy, jako jsou struktury a výčty. Nelze ji také použít k "přidání" metody do zapečetěné třídy.

Metody rozšíření umožňují přidat metodu do existujícího typu beze změny samotného typu nebo implementace nové metody v zděděného typu. Rozšiřující metoda také nemusí být umístěna ve stejném sestavení jako typ, který rozšiřuje. Voláte metodu rozšíření, jako by byla definovaná člena typu.

Další informace naleznete v tématu Metody rozšíření.

Asynchronní metody

Pomocí asynchronní funkce můžete vyvolat asynchronní metody bez použití explicitních zpětných volání nebo ručního rozdělení kódu mezi více metod nebo výrazů lambda.

Pokud metodu označíte modifikátorem async , můžete v metodě použít operátor await . Když ovládací prvek dosáhne await výrazu v asynchronní metodě, ovládací prvek se vrátí volajícímu, pokud není dokončen očekávaný úkol, a průběh v metodě s klíčovým slovem await se pozastaví, dokud očekávaný úkol nedokončí. Po dokončení úlohy může provádění v metodě pokračovat.

Poznámka

Asynchronní metoda se vrátí volajícímu, když dojde buď k prvnímu očekávanému objektu, který ještě není dokončený, nebo se dostane na konec asynchronní metody, podle toho, co nastane dříve.

Asynchronní metoda má obvykle návratový Task<TResult>typ , Task, IAsyncEnumerable<T>, nebo void. Návratový void typ se používá především k definování obslužných rutin událostí, kde je vyžadován návratový void typ. Asynchronní metoda, která vrací void , nelze očekávat a volající metody void-returning nemůže zachytit výjimky, které metoda vyvolá. Asynchronní metoda může mít libovolný návratový typ podobný úkolu.

V následujícím příkladu je asynchronní metoda, DelayAsync která má návratový příkaz, který vrací celé číslo. Vzhledem k tomu, že se jedná o asynchronní metodu, musí mít deklarace metody návratový Task<int>typ . Vzhledem k tomu, že návratový typ je Task<int>, vyhodnocení výrazu await v DoSomethingAsync vytvoří celé číslo, jak ukazuje následující int result = await delayTask příkaz.

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

Asynchronní metoda nemůže deklarovat žádné parametry, ref nebo out, ale může volat metody, které mají tyto parametry.

Další informace o asynchronních metodách naleznete v tématu Asynchronní programování s asynchronní a await a asynchronní návratové typy.

Členové tvoření výrazy

Definice metod, které se vrací okamžitě s výsledkem výrazu, nebo které mají jediný příkaz jako tělo metody, je běžné. Existuje zástupce syntaxe pro definování takových metod pomocí =>:

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);

Pokud metoda vrátí void nebo je asynchronní metoda, tělo metody musí být výraz příkazu (stejný jako u lambdas). U vlastností a indexerů musí být jen pro čtení a nepoužíváte klíčové slovo přístupového objektu get .

Iterátory

Iterátor provádí vlastní iteraci v kolekci, například seznam nebo pole. Iterátor používá příkaz yield return k vrácení každého prvku vždy po druhém. yield return Po dosažení příkazu se aktuální umístění zapamatuje, aby volající mohl požádat o další prvek v sekvenci.

Návratový typ iterátoru může být IEnumerable, IEnumerable<T>, IAsyncEnumerable<T>, IEnumerator, nebo IEnumerator<T>.

Další informace najdete v tématu Iterátory.

Viz také