Methoden (C#-Programmierhandbuch)

Eine Methode ist ein Codeblock, der eine Reihe von Anweisungen enthält. Ein Programm bewirkt die Ausführung der Anweisungen, indem die Methode aufgerufen wird und alle erforderlichen Methodenargumente angegeben werden. In C# werden alle Anweisungen im Kontext einer Methode ausgeführt. Die Main-Methode ist der Einstiegspunkt jeder C#-Anwendung und wird von der Common Language Runtime (CLR) aufgerufen, wenn das Programm gestartet wird.

Hinweis

In diesem Thema werden benannte Methoden erläutert. Informationen über anonyme Funktionen finden Sie unter Anonyme Funktionen.

Methodensignaturen

Methoden werden in einer Klasse oder Struktur deklariert, indem die Zugriffsebene wie z. B. public oder private, optionale Modifizierer wie z. B. abstract oder sealed, der Rückgabewert, der Name der Methode und die Methodenparameter angegeben werden. Diese Teile bilden zusammen die Signatur der Methode.

Hinweis

Ein Rückgabetyp einer Methode ist nicht Teil der Signatur der Methode, wenn es um die Methodenüberladung geht. Er ist jedoch Teil der Methodensignatur, wenn die Kompatibilität zwischen einem Delegaten und der Methode bestimmt wird, auf die dieser verweist.

Methodenparameter werden in Klammern eingeschlossen und durch Kommas getrennt. Leere Klammern geben an, dass für die Methode keine Parameter erforderlich sind. Diese Klasse enthält drei Methoden:

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 must implement this.
    public abstract double GetTopSpeed(); 
}

Methodenzugriff

Das Aufrufen einer Methode für ein Objekt ähnelt dem Zugreifen auf ein Feld. Fügen Sie nach dem Objektnamen einen Punkt, den Namen der Methode und Klammern hinzu. Argumente werden innerhalb der Klammern aufgelistet und durch Kommas getrennt. Die Methoden der Motorcycle -Klasse können also wie im folgenden Beispiel gezeigt aufgerufen werden:

class TestMotorcycle : Motorcycle
{

    public override double GetTopSpeed()
    {
        return 108.4;
    }

    static void Main()
    {
        
        TestMotorcycle moto = new TestMotorcycle();

        moto.StartEngine();
        moto.AddGas(15);
        moto.Drive(5, 20);
        double speed = moto.GetTopSpeed();
        Console.WriteLine("My top speed is {0}", speed);            
    }
}

Methodenparameter und Argumente

Die Methodendefinition gibt die Namen und Typen aller ggf. erforderlichen Parameter an. Wenn aufrufender Code die Methode aufruft, werden für jeden Parameter konkrete Werte bereitgestellt, die als Argumente bezeichnet werden. Die Argumente müssen mit dem Parametertyp kompatibel sein, aber der im aufrufenden Code verwendete Name des Arguments (sofern vorhanden) muss nicht mit dem in der Methode definierten Parameternamen identisch sein. Zum Beispiel:

public void Caller()
{
    int numA = 4;
    // Call with an int variable.
    int productA = Square(numA);

    int numB = 32;
    // Call with another int variable.
    int productB = Square(numB);

    // Call with an integer literal.
    int productC = Square(12);

    // Call with an expression that evaulates to int.
    productC = Square(productA * 3);
}

int Square(int i)
{
    // Store input argument in a local variable.
    int input = i;
    return input * input;
}

Übergeben als Verweis und Übergeben als Wert

Wenn ein Werttyp an eine Methode übergeben wird, wird anstelle des eigentlichen Objekts standardmäßig eine Kopie übergeben. Änderungen am Argument haben daher keine Auswirkungen auf die ursprüngliche Kopie in der aufrufenden Methode. Sie können einen Werttyp als Verweis übergeben, indem Sie das ref-Schlüsselwort verwenden. Weitere Informationen finden Sie unter Übergeben von Werttypparametern. Eine Liste der integrierten Werttypen finden Sie unter Tabelle der Typen und Variablen.

Wenn ein Objekt eines Verweistyps an eine Methode übergeben wird, wird ein Verweis auf das Objekt übergeben. Das heißt, die Methode erhält nicht das Objekt selbst, sondern ein Argument, das den Speicherort des Objekts angibt. Wenn Sie einen Member des Objekts unter Verwendung dieses Verweises ändern, wird die Änderung im Argument in der aufrufenden Methode berücksichtigt, selbst wenn Sie das Objekt als Wert übergeben.

Sie erstellen einen Verweistyp mithilfe des class -Schlüsselworts, wie im folgenden Beispiel gezeigt.

public class SampleRefType
{
    public int value;
}

Wenn Sie jetzt ein Objekt, das auf diesem Typ basiert, an eine Methode übergeben, wird ein Verweis auf das Objekt übergeben. Das folgende Beispiel übergibt ein Objekt des SampleRefType -Typs an die ModifyObject-Methode.

public static void TestRefType()
{
    SampleRefType rt = new SampleRefType();
    rt.value = 44;
    ModifyObject(rt);
    Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
    obj.value = 33;
}

Das Beispiel entspricht im Wesentlichen dem vorherigen Beispiel und übergibt ein Argument als Wert an eine Methode. Aber da ein Verweistyp verwendet wird, unterscheidet sich das Ergebnis. Die Änderung, die in ModifyObject am value -Feld des Parameters ( obj) vorgenommen wird, ändert auch das value -Feld des Arguments ( rt) in der TestRefType -Methode. Die TestRefType -Methode zeigt 33 als Ausgabe an.

Weitere Informationen zum Übergeben von Verweistypen als Verweis oder als Wert finden Sie unter Übergeben von Verweistypparametern und Verweistypen.

Rückgabewerte

Methoden können einen Wert an die aufrufende Funktion (den Aufrufer) zurückgeben. Wenn der Rückgabetyp – der vor dem Methodennamen aufgeführte Typ – nicht voidist, kann die Methode den Wert mithilfe des return -Schlüsselworts zurückgeben. Eine Anweisung mit der return -Schlüsselwort, gefolgt von einem Wert, der dem Rückgabetyp entspricht, gibt diesen Wert an den Methodenaufrufer zurück.

Der Wert kann an den Aufrufer nach Wert oder, ab C# 7, nach Verweis zurückgegeben werden. Werte werden an den Aufrufer nach Verweis zurückgegeben, wenn das Schlüsselwort ref in der Methodensignatur verwendet wird und auf jedes return-Schlüsselwort folgt. Die folgende Methodensignatur und Rückgabeanweisung geben an, dass die Methode eine Variable mit dem Namen estDistance nach Verweis an den Aufrufer zurückgibt.

public ref double GetEstimatedDistance()
{
   return ref estDistance;
}

Das return -Schlüsselwort beendet außerdem die Ausführung der Methode. Wenn der Rückgabetyp voidist, ist eine return -Anweisung ohne Wert immer noch nützlich, um die Ausführung der Methode zu beenden. Ohne das return -Schlüsselwort wird die Ausführung der Methode beendet, wenn das Ende des Codeblocks erreicht ist. Methoden mit einem anderen Rückgabetyp als „void“ müssen das return -Schlüsselwort verwenden, um einen Wert zurückzugeben. Die folgenden beiden Methoden verwenden z. B. das return -Schlüsselwort, um ganze Zahlen zurückzugeben:

class SimpleMath
{
    public int AddTwoNumbers(int number1, int number2)
    {
        return number1 + number2;
    }

    public int SquareANumber(int number)
    {
        return number * number;
    }
}

Um einen von einer Methode zurückgegebenen Wert zu verwenden, kann die aufrufende Methode den Methodenaufruf selbst an jeder Stelle verwenden, an der ein Wert des gleichen Typs ausreichend ist. Sie können den Rückgabewert auch einer Variablen zuweisen. Beispielsweise wird mit den folgenden beiden Codebeispiele das gleiche Ergebnis erzielt:

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

Die Verwendung einer lokalen Variablen, in diesem Fall result, zum Speichern eines Werts ist optional. Es kann die Lesbarkeit des Codes verbessern, oder es kann notwendig sein, wenn Sie den ursprünglichen Wert des Arguments für den gesamten Gültigkeitsbereich der Methode speichern müssen.

Um einen Wert zu verwenden, der nach Verweis von einer Methode zurückgegeben wurde, müssen Sie die Variable ref local deklarieren, wenn Sie diesen Wert modifizieren möchten. Wenn die Planet.GetEstimatedDistance-Methode z.B. einen <xref:System.Double>-Wert nach Verweis zurückgibt, können Sie ihn mit Code wie dem folgenden als ref local-Variable definieren:

ref int distance = plant 

Die Zurückgabe eines mehrdimensionalen Arrays aus einer Methode, M, die den Inhalt eines Arrays modifiziert, ist nicht vonnöten, wenn die aufrufende Funktion das Array an M übergeben hat. Sie können das resultierende Array aus M für den funktionalen Fluss der Werte oder aus stilistischen Gründen zurückgeben. Dies ist jedoch nicht nötig, da C# alle Referenztypen nach Wert übergibt und der Wert eines Arrayverweises ein Zeiger auf das Array ist. In der Methode M sind Änderungen am Inhalt des Arrays durch beliebigen Code beobachtbar, der einen Verweis auf das Array enthält, wie im folgenden Beispiel gezeigt.

static void Main(string[] args)  
        {  
            int[,] matrix = new int[2, 2];  
            FillMatrix(matrix);  
            // matrix is now full of -1  
        }  

        public static void FillMatrix(int[,] matrix)  
        {  
            for (int i = 0; i < matrix.GetLength(0); i++)  
            {  
                for (int j = 0; j < matrix.GetLength(1); j++)  
                {  
                    matrix[i, j] = -1;  
                }  
            }  
        }  

Weitere Informationen finden Sie unter return.

Asynchrone Methoden

Mithilfe der Async-Funktion können Sie asynchrone Methoden aufrufen, ohne explizite Rückrufe verwenden oder den Code manuell über mehrere Methoden oder Lambda-Ausdrücke teilen zu müssen.

Wenn Sie eine Methode mit dem async -Modifizierer kennzeichnen, können Sie den await Operator in der Methode verwenden. Wenn ein await-Ausdruck in der asynchronen Methode erreicht wird, wird die Steuerung an den Aufrufer zurückgegeben, und die Ausführung der Methode wird angehalten, bis die erwartete Aufgabe abgeschlossen ist. Wenn die Aufgabe abgeschlossen ist, kann die Ausführung in der Methode fortgesetzt werden.

Hinweis

Eine asynchrone Methode wird an den Aufrufer zurückgegeben, wenn sie entweder auf das erste erwartete Objekt trifft, das noch nicht abgeschlossen wurde, oder das Ende der asynchronen Methode erreicht.

Eine asynchrone Methode kann den Rückgabetyp <xref:System.Threading.Tasks.Task%601>, <xref:System.Threading.Tasks.Task>oder „void“ haben. Der void-Rückgabetyp wird hauptsächlich zum Definieren von Ereignishandlern verwendet, bei denen ein void-Rückgabetyp erforderlich ist. Auf eine asynchrone Methode, die „void“ zurückgibt, kann nicht gewartet werden, und der Aufrufer einer Methode mit void-Rückgabe kann keine Ausnahmen auffangen, die die Methode auslöst.

Im folgenden Beispiel ist DelayAsync eine asynchrone Methode mit dem Rückgabetyp <xref:System.Threading.Tasks.Task%601>. DelayAsync enthält eine return -Anweisung, die eine ganze Zahl zurückgibt. Aus diesem Grund muss die Methodendeklaration von DelayAsync den Rückgabetyp Task<int>haben. Da der Rückgabetyp Task<int>ist, ergibt die Auswertung des await -Ausdrucks in DoSomethingAsync eine ganze Zahl, wie die folgende Anweisung veranschaulicht: int result = await delayTask.

Die startButton_Click -Methode ist ein Beispiel für eine asynchrone Methode mit void-Rückgabetyp. Da DoSomethingAsync eine asynchrone Methode ist, muss die Aufgabe für den Aufruf von DoSomethingAsync abgewartet werden, wie in der folgenden Anweisung dargestellt: await DoSomethingAsync();. Die startButton_Click -Methode muss mit dem async -Modifizierer definiert werden, da die Methode über einen await -Ausdruck verfügt.

// using System.Diagnostics;
// using System.Threading.Tasks;

// This Click event is marked with the async modifier.
private async void startButton_Click(object sender, RoutedEventArgs e)
{
    await DoSomethingAsync();
}

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

    Debug.WriteLine("Result: " + result);
}

private async Task<int> DelayAsync()
{
    await Task.Delay(100);
    return 5;
}

// Output:
//  Result: 5

Mit einer asynchronen Methode können keine ref - oder out -Parameter deklariert, jedoch Methoden aufgerufen werden, die solche Parameter aufweisen.

Weitere Informationen über asynchrone Methoden finden Sie unter Asynchronous Programming with async and await (Asynchrone Programmierung mit Async und Await), Ablaufsteuerung in asynchronen Programmen und Asynchrone Rückgabetypen.

Ausdruckstextdefinitionen

Es gibt häufig Methodendefinitionen, die einfach direkt das Ergebnis eines Ausdrucks zurückgeben oder eine einzige Anweisung als Text der Methode aufweisen. Es ist eine Syntaxabkürzung zur Definition solcher Methoden mithilfe von =>verfügbar:

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

Wenn die Methode void zurückgibt oder es sich um eine asynchrone Methode handelt, muss der Text der Methode ein Anweisungsausdruck sein (wie bei Lambdas). Eigenschaften und Indexer müssen schreibgeschützt sein. Verwenden Sie darüber hinaus nicht das get-Accessorschlüsselwort.

Iteratoren

Ein Iterator führt eine benutzerdefinierte Iteration durch eine Auflistung durch, z. B. eine Liste oder ein Array. Ein Iterator verwendet die yield return -Anweisung, um jedes Element einzeln nacheinander zurückzugeben. Wenn eine yield return -Anweisung erreicht wird, wird die aktuelle Position im Code gespeichert. Wenn der Iterator das nächste Mal aufgerufen wird, wird die Ausführung von dieser Position neu gestartet.

Sie rufen einen Iterator im Clientcode mithilfe einer foreach Anweisung auf.

Der Rückgabetyp eines Iterators kann <xref:System.Collections.IEnumerable>, <xref:System.Collections.Generic.IEnumerable%601>, <xref:System.Collections.IEnumerator>oder <xref:System.Collections.Generic.IEnumerator%601>sein.

Weitere Informationen finden Sie unter Iteratoren.

C#-Programmiersprachenspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

C#-Programmierhandbuch
Klassen und Strukturen
Zugriffsmodifizierer
Statische Klassen und statische Klassenmember
Vererbung
Abstrakte und versiegelte Klassen und Klassenmember
params
return
out
ref
Übergeben von Parametern