Training
Module
C#-methoden maken die waarden retourneren - Training
Deze module bevat informatie over het retourwoord en het retourneren van waarden uit methoden.
Deze browser wordt niet meer ondersteund.
Upgrade naar Microsoft Edge om te profiteren van de nieuwste functies, beveiligingsupdates en technische ondersteuning.
Een methode is een codeblok dat een reeks instructies bevat. Een programma zorgt ervoor dat de instructies worden uitgevoerd door de methode aan te roepen en eventuele vereiste methodeargumenten op te geven. In C# wordt elke uitgevoerde instructie uitgevoerd in de context van een methode.
Notitie
In dit onderwerp worden benoemde methoden besproken. Zie Lambda-expressies voor informatie over anonieme functies.
Methoden worden gedeclareerd in een class
, record
of struct
door het volgende op te geven:
public
of private
. De standaardwaarde is private
.abstract
of sealed
.void
als de methode geen heeft.Deze onderdelen vormen samen de methodehandtekening.
Belangrijk
Een retourtype van een methode maakt geen deel uit van de handtekening van de methode voor overbelasting van de methode. Het maakt echter deel uit van de handtekening van de methode bij het bepalen van de compatibiliteit tussen een gemachtigde en de methode waarnaar deze verwijst.
In het volgende voorbeeld wordt een klasse gedefinieerd met de naam Motorcycle
vijf methoden:
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();
}
De Motorcycle
klasse bevat een overbelaste methode. Drive
Twee methoden hebben dezelfde naam, maar worden onderscheiden door hun parametertypen.
Methoden kunnen exemplaar of statisch zijn. U moet een object instantiëren om een exemplaarmethode op dat exemplaar aan te roepen; een instantiemethode werkt op dat exemplaar en de bijbehorende gegevens. U roept een statische methode aan door te verwijzen naar de naam van het type waartoe de methode behoort; statische methoden werken niet op exemplaargegevens. Als u een statische methode probeert aan te roepen via een objectexemplaren, wordt er een compilerfout gegenereerd.
Het aanroepen van een methode lijkt op het openen van een veld. Voeg na de objectnaam (als u een exemplaarmethode aanroept) of de typenaam (als u een static
methode aanroept), een punt, de naam van de methode en haakjes toe. Argumenten worden tussen haakjes weergegeven en worden gescheiden door komma's.
Met de methodedefinitie worden de namen en typen parameters opgegeven die vereist zijn. Wanneer een aanroeper de methode aanroept, worden voor elke parameter concrete waarden, argumenten genoemd, weergegeven. De argumenten moeten compatibel zijn met het parametertype, maar de argumentnaam, als deze wordt gebruikt in de aanroepende code, hoeft niet hetzelfde te zijn als de parameter die in de methode is gedefinieerd. In het volgende voorbeeld bevat de Square
methode één parameter van het type int
i. De eerste methodeaanroep geeft de Square
methode een variabele van het type int
num door; de tweede, een numerieke constante en de derde, een expressie.
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;
}
}
De meest voorkomende vorm van methodeaanroepen gebruikte positionele argumenten; het levert argumenten in dezelfde volgorde als methodeparameters. De methoden van de Motorcycle
klasse kunnen daarom worden aangeroepen zoals in het volgende voorbeeld. De aanroep van de Drive
methode bevat bijvoorbeeld twee argumenten die overeenkomen met de twee parameters in de syntaxis van de methode. De eerste wordt de waarde van de miles
parameter. De tweede wordt de waarde van de speed
parameter.
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);
}
}
U kunt ook benoemde argumenten gebruiken in plaats van positionele argumenten bij het aanroepen van een methode. Wanneer u benoemde argumenten gebruikt, geeft u de parameternaam op, gevolgd door een dubbele punt (:) en het argument. Argumenten voor de methode kunnen in elke volgorde worden weergegeven, zolang alle vereiste argumenten aanwezig zijn. In het volgende voorbeeld worden benoemde argumenten gebruikt om de TestMotorcycle.Drive
methode aan te roepen. In dit voorbeeld worden de benoemde argumenten doorgegeven in de tegenovergestelde volgorde van de parameterlijst van de methode.
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
U kunt een methode aanroepen met zowel positionele argumenten als benoemde argumenten. Positionele argumenten kunnen echter alleen benoemde argumenten volgen wanneer de benoemde argumenten zich in de juiste posities bevinden. In het volgende voorbeeld wordt de TestMotorcycle.Drive
methode uit het vorige voorbeeld aangeroepen met behulp van één positioneel argument en één benoemd argument.
int travelTime = moto.Drive(170, speed: 55);
Naast de leden die expliciet zijn gedefinieerd in een type, neemt een type leden over die zijn gedefinieerd in de basisklassen. Omdat alle typen in het beheerde typesysteem direct of indirect overnemen van de Object klasse, nemen alle typen de leden over, zoals Equals(Object), GetType()en ToString(). In het volgende voorbeeld wordt een Person
klasse gedefinieerd, worden twee Person
objecten geïnstitueert en wordt de Person.Equals
methode aangeroepen om te bepalen of de twee objecten gelijk zijn. De Equals
methode is echter niet gedefinieerd in de Person
klasse; deze wordt overgenomen van 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
Typen kunnen overgenomen leden overschrijven met behulp van het override
trefwoord en een implementatie bieden voor de overschreven methode. De methodehandtekening moet hetzelfde zijn als de overschreven methode. Het volgende voorbeeld lijkt op de vorige, behalve dat de Equals(Object) methode wordt overschreven. (De methode wordt ook overschreven GetHashCode() , omdat de twee methoden zijn bedoeld om consistente resultaten te bieden.)
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
Typen in C# zijn waardetypen of verwijzingstypen. Zie Typen voor een lijst met ingebouwde waardetypen. Standaard worden zowel waardetypen als verwijzingstypen doorgegeven aan een methode.
Wanneer een waardetype wordt doorgegeven aan een methode op waarde, wordt een kopie van het object in plaats van het object zelf doorgegeven aan de methode. Wijzigingen in het object in de aangeroepen methode hebben daarom geen effect op het oorspronkelijke object wanneer het besturingselement terugkeert naar de aanroeper.
In het volgende voorbeeld wordt een waardetype doorgegeven aan een methode op waarde en de aangeroepen methode probeert de waarde van het waardetype te wijzigen. Het definieert een variabele van het type int
, een waardetype, initialiseert de waarde ervan naar 20 en geeft deze door aan een methode met de naam ModifyValue
die de waarde van de variabele wijzigt in 30. Wanneer de methode echter retourneert, blijft de waarde van de variabele ongewijzigd.
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
Wanneer een object van een verwijzingstype wordt doorgegeven aan een methode op waarde, wordt een verwijzing naar het object doorgegeven door een waarde. Dat wil gezegd, de methode ontvangt niet het object zelf, maar een argument dat de locatie van het object aangeeft. Als u een lid van het object wijzigt met behulp van deze verwijzing, wordt de wijziging doorgevoerd in het object wanneer het besturingselement terugkeert naar de aanroepmethode. Het vervangen van het object dat aan de methode is doorgegeven, heeft echter geen effect op het oorspronkelijke object wanneer het besturingselement terugkeert naar de aanroeper.
In het volgende voorbeeld wordt een klasse (een verwijzingstype) met de naam SampleRefType
gedefinieerd. Er wordt een SampleRefType
object geïnstitueert, 44 aan het value
veld toegewezen en het object doorgegeven aan de ModifyObject
methode. Dit voorbeeld doet in wezen hetzelfde als in het vorige voorbeeld: het geeft een argument per waarde door aan een methode. Maar omdat een verwijzingstype wordt gebruikt, is het resultaat anders. De wijziging die in ModifyObject
het obj.value
veld wordt aangebracht, wijzigt ook het value
veld van het argument, rt
in de Main
methode in 33, zoals de uitvoer uit het voorbeeld laat zien.
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;
}
U geeft een parameter door aan de hand van een verwijzing wanneer u de waarde van een argument in een methode wilt wijzigen en deze wijziging wilt weergeven wanneer het besturingselement terugkeert naar de aanroepmethode. Als u een parameter per verwijzing wilt doorgeven, gebruikt u het ref
of out
trefwoord. U kunt ook een waarde doorgeven door te verwijzen om kopiëren te voorkomen, maar nog steeds wijzigingen te voorkomen met behulp van het in
trefwoord.
Het volgende voorbeeld is identiek aan de vorige, behalve dat de waarde wordt doorgegeven door verwijzing naar de ModifyValue
methode. Wanneer de waarde van de parameter wordt gewijzigd in de ModifyValue
methode, wordt de wijziging in waarde weerspiegeld wanneer het besturingselement terugkeert naar de aanroeper.
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
Een gemeenschappelijk patroon dat door refparameters wordt gebruikt, omvat het wisselen van de waarden van variabelen. U geeft twee variabelen door aan een methode op basis van verwijzing en de methode wisselt de inhoud ervan. In het volgende voorbeeld worden gehele getallen gewisseld.
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
Door een parameter voor het verwijzingstype door te geven, kunt u de waarde van de verwijzing zelf wijzigen in plaats van de waarde van de afzonderlijke elementen of velden.
Soms is de vereiste die u opgeeft het exacte aantal argumenten voor uw methode beperkend. Door het params
trefwoord te gebruiken om aan te geven dat een parameter een parameterverzameling is, kunt u de methode aangeroepen met een variabel aantal argumenten. De parameter die is getagd met het params
trefwoord, moet een verzamelingstype zijn en moet de laatste parameter in de parameterlijst van de methode zijn.
Een aanroeper kan vervolgens de methode op vier manieren aanroepen voor de params
parameter:
null
.In het volgende voorbeeld wordt een methode gedefinieerd die GetVowels
alle klinkers uit een parameterverzameling retourneert. De Main
methode illustreert alle vier de manieren om de methode aan te roepen. Bellers hoeven geen argumenten op te geven voor parameters die de params
wijzigingsfunctie bevatten. In dat geval is de parameter een lege verzameling.
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: ''
Voor C# 13 kan de params
modifier alleen worden gebruikt met één dimensionale matrix.
Een methodedefinitie kan opgeven dat de parameters vereist zijn of dat ze optioneel zijn. Standaard zijn parameters vereist. Optionele parameters worden opgegeven door de standaardwaarde van de parameter op te geven in de methodedefinitie. Wanneer de methode wordt aangeroepen en er geen argument wordt opgegeven voor een optionele parameter, wordt in plaats daarvan de standaardwaarde gebruikt.
U wijst de standaardwaarde van de parameter toe met een van de volgende soorten expressies:
Een constante, zoals een letterlijke tekenreeks of een getal.
Een expressie van het formulier default(SomeType)
, waarbij SomeType
dit een waardetype of een verwijzingstype kan zijn. Als het een verwijzingstype is, is dit in feite hetzelfde als het opgeven null
. U kunt de default
letterlijke waarde gebruiken, omdat de compiler het type kan afleiden uit de declaratie van de parameter.
Een expressie van het formulier new ValType()
, waarbij ValType
een waardetype is. Met deze expressie wordt de impliciete parameterloze constructor van het waardetype aangeroepen. Dit is geen echt lid van het type.
Notitie
Wanneer in C# 10 en hoger een expressie van het formulier new ValType()
de expliciet gedefinieerde parameterloze constructor van een waardetype aanroept, genereert de compiler een fout als de standaardparameterwaarde een compilatieconstante moet zijn. Gebruik de default(ValType)
expressie of de default
letterlijke waarde om de standaardparameterwaarde op te geven. Zie de sectie Struct initialisatie en standaardwaarden van het artikel Structuurtypen voor meer informatie over parameterloze constructors.
Als een methode zowel vereiste als optionele parameters bevat, worden optionele parameters aan het einde van de parameterlijst gedefinieerd, na alle vereiste parameters.
In het volgende voorbeeld wordt een methode gedefinieerd met ExampleMethod
één vereiste en twee optionele parameters.
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);
}
}
De aanroeper moet een argument opgeven voor alle optionele parameters tot de laatste optionele parameter waarvoor een argument wordt opgegeven. Als de aanroeper in de ExampleMethod
methode bijvoorbeeld een argument voor de description
parameter levert, moet deze er ook een opgeven voor de optionalInt
parameter. opt.ExampleMethod(2, 2, "Addition of 2 and 2");
is een geldige methode-aanroep; opt.ExampleMethod(2, , "Addition of 2 and 0");
genereert een compilerfout 'Argument ontbreekt'.
Als een methode wordt aangeroepen met behulp van benoemde argumenten of een combinatie van positionele en benoemde argumenten, kan de aanroeper alle argumenten weglaten die volgen op het laatste positionele argument in de methodeaanroep.
In het volgende voorbeeld wordt de ExampleMethod
methode drie keer aangeroepen. Bij de eerste twee methodeaanroepen worden positionele argumenten gebruikt. De eerste weglaat beide optionele argumenten, terwijl de tweede het laatste argument weglaat. De derde methodeaanroep levert een positioneel argument voor de vereiste parameter, maar gebruikt een benoemd argument om een waarde op te geven aan de description
parameter terwijl het optionalInt
argument wordt weggelaten.
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
Het gebruik van optionele parameters is van invloed op overbelastingsresolutie of de manier waarop de C#-compiler bepaalt welke overbelasting moet worden aangeroepen voor een methode-aanroep, als volgt:
Methoden kunnen een waarde retourneren aan de aanroeper. Als het retourtype (het type dat wordt vermeld vóór de naam van de methode) niet void
is, kan de methode de waarde retourneren met behulp van het return
trefwoord. Een instructie met het return
trefwoord gevolgd door een variabele, constante of expressie die overeenkomt met het retourtype retourneert die waarde aan de aanroeper van de methode. Methoden met een niet-void-retourtype zijn vereist om het return
trefwoord te gebruiken om een waarde te retourneren. Het return
trefwoord stopt ook de uitvoering van de methode.
Als het retourtype is void
, is een return
instructie zonder waarde nog steeds nuttig om de uitvoering van de methode te stoppen. Zonder het return
trefwoord wordt de methode niet meer uitgevoerd wanneer het einde van het codeblok wordt bereikt.
Met deze twee methoden wordt bijvoorbeeld het return
trefwoord gebruikt om gehele getallen te retourneren:
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2) =>
number1 + number2;
public int SquareANumber(int number) =>
number * number;
}
De bovenstaande voorbeelden zijn expressieleden. Expressieleden retourneren de waarde die door de expressie wordt geretourneerd.
U kunt er ook voor kiezen om uw methoden te definiëren met een hoofdtekst van de instructie en een return
instructie:
class SimpleMathExtnsion
{
public int DivideTwoNumbers(int number1, int number2)
{
return number1 / number2;
}
}
Als u een waarde wilt gebruiken die wordt geretourneerd door een methode, kan de aanroepende methode overal een waarde van hetzelfde type gebruiken. U kunt de retourwaarde ook toewijzen aan een variabele. De volgende drie codevoorbeelden bereiken bijvoorbeeld hetzelfde doel:
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);
Soms wilt u dat uw methode meer dan één waarde retourneert. U gebruikt tuple-typen en tuple-letterlijke waarden om meerdere waarden te retourneren. Het tuple-type definieert de gegevenstypen van de tuple-elementen. Letterlijke waarden van tuple bieden de werkelijke waarden van de geretourneerde tuple. In het volgende voorbeeld (string, string, string, int)
definieert u het tuple-type dat door de GetPersonalInfo
methode wordt geretourneerd. De expressie (per.FirstName, per.MiddleName, per.LastName, per.Age)
is de letterlijke tuple. De methode retourneert de eerste, middelste en familienaam, samen met de leeftijd van een PersonInfo
object.
public (string, string, string, int) GetPersonalInfo(string id)
{
PersonInfo per = PersonInfo.RetrieveInfoById(id);
return (per.FirstName, per.MiddleName, per.LastName, per.Age);
}
De aanroeper kan vervolgens de geretourneerde tuple gebruiken met behulp van de volgende code:
var person = GetPersonalInfo("111111111");
Console.WriteLine($"{person.Item1} {person.Item3}: age = {person.Item4}");
Namen kunnen ook worden toegewezen aan de tuple-elementen in de definitie van het tuple-type. In het volgende voorbeeld ziet u een alternatieve versie van de GetPersonalInfo
methode die gebruikmaakt van benoemde elementen:
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);
}
De vorige aanroep van de GetPersonalInfo
methode kan vervolgens als volgt worden gewijzigd:
var person = GetPersonalInfo("111111111");
Console.WriteLine($"{person.FName} {person.LName}: age = {person.Age}");
Als een methode een matrix als parameter gebruikt en de waarde van afzonderlijke elementen wijzigt, is het niet nodig dat de methode de matrix retourneert. C# geeft alle verwijzingstypen op waarde door en de waarde van een matrixreferentie is de aanwijzer naar de matrix. In het volgende voorbeeld zijn wijzigingen in de inhoud van de values
matrix die in de DoubleValues
methode zijn aangebracht, waarneembaar door code die een verwijzing naar de matrix bevat.
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
Normaal gesproken zijn er twee manieren om een methode toe te voegen aan een bestaand type:
Met extensiemethoden kunt u een methode toevoegen aan een bestaand type zonder het type zelf te wijzigen of de nieuwe methode in een overgenomen type te implementeren. De extensiemethode hoeft zich ook niet in dezelfde assembly te bevinden als het type dat het uitbreidt. U roept een extensiemethode aan alsof het een gedefinieerd lid van een type is.
Zie Extensiemethoden voor meer informatie.
Met behulp van de asynchrone functie kunt u asynchrone methoden aanroepen zonder expliciete callbacks te gebruiken of uw code handmatig te splitsen over meerdere methoden of lambda-expressies.
Als u een methode markeert met de asynchrone wijziging, kunt u de wachtoperator in de methode gebruiken. Wanneer het besturingselement een await
expressie in de asynchrone methode bereikt, keert het besturingselement terug naar de aanroeper als de wachtende taak niet is voltooid en wordt de voortgang in de methode met het await
trefwoord opgeschort totdat de wachtende taak is voltooid. Wanneer de taak is voltooid, kan de uitvoering worden hervat in de methode.
Notitie
Een asynchrone methode keert terug naar de aanroeper wanneer het het eerste wachtende object tegenkomt dat nog niet is voltooid of het einde van de asynchrone methode bereikt, afhankelijk van wat zich het eerst voordoet.
Een asynchrone methode heeft meestal een retourtype Task<TResult>, Taskof IAsyncEnumerable<T>void
. Het void
retourtype wordt voornamelijk gebruikt om gebeurtenis-handlers te definiëren, waarbij een void
retourtype vereist is. Een asynchrone methode die retourneert void
, kan niet worden gewacht en de aanroeper van een methode voor het retourneren van ongeldige gegevens kan geen uitzonderingen vangen die de methode genereert. Een asynchrone methode kan elk taakachtig retourtype hebben.
In het volgende voorbeeld DelayAsync
is een asynchrone methode met een retourinstructie die een geheel getal retourneert. Omdat het een asynchrone methode is, moet de declaratie van Task<int>
de methode een retourtype hebben. Omdat het retourtype is Task<int>
, produceert de evaluatie van de await
expressie in DoSomethingAsync
een geheel getal, zoals de volgende int result = await delayTask
instructie laat zien.
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
Een asynchrone methode kan geen parameters in, verw of out declareren, maar kan methoden aanroepen die dergelijke parameters hebben.
Zie Asynchrone programmering met asynchrone asynchrone typen en wachten en Asynchroon retourneren voor meer informatie over asynchrone methoden.
Het is gebruikelijk om methodedefinities te hebben die direct worden geretourneerd met het resultaat van een expressie of die één instructie hebben als hoofdtekst van de methode. Er is een syntaxissnelkoppeling voor het definiëren van dergelijke methoden met behulp van =>
:
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);
Als de methode retourneert void
of een asynchrone methode is, moet de hoofdtekst van de methode een instructieexpressie zijn (hetzelfde als bij lambdas). Voor eigenschappen en indexeerfuncties moeten ze alleen-lezen zijn en u gebruikt het get
trefwoord accessor niet.
Een iterator voert een aangepaste iteratie uit voor een verzameling, zoals een lijst of een matrix. Een iterator gebruikt de rendementsinstructie om elk element één voor één te retourneren. Wanneer een yield return
instructie wordt bereikt, wordt de huidige locatie onthouden, zodat de beller het volgende element in de reeks kan aanvragen.
Het retourtype van een iterator kan zijnIEnumerable, of IAsyncEnumerable<T>IEnumerable<T>IEnumeratorIEnumerator<T>.
Zie Iterators voor meer informatie.
.NET-feedback
.NET is een open source project. Selecteer een koppeling om feedback te geven:
Training
Module
C#-methoden maken die waarden retourneren - Training
Deze module bevat informatie over het retourwoord en het retourneren van waarden uit methoden.