Freigeben über


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 für jede C#-Anwendung und wird beim Starten des Programms von der Common Language Runtime (CLR) aufgerufen. In einer Anwendung, die Anweisungen der obersten Ebene verwendet, wird die Main Methode vom Compiler generiert und enthält alle Anweisungen der obersten Ebene.

Hinweis

In diesem Artikel werden benannte Methoden erläutert. Weitere Informationen zu anonymen Funktionen finden Sie unter Lambdaausdrücke.

Methodensignaturen

Methoden werden in einer Klasse, Struktur oder Schnittstelle deklariert, indem sie die Zugriffsebene angeben, z public . B. optionale privateModifizierer wie abstract oder sealed, den Rückgabewert, den Namen der Methode und alle Methodenparameter. Diese Teile sind die Signatur der Methode.

Von Bedeutung

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 vier 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 ist wie der Zugriff 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 daher wie im folgenden Beispiel 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 {speed}");
    }
}

Methodenparameter im Vergleich zu Argumenten

Die Methodendefinition gibt die Namen und Typen aller ggf. erforderlichen Parameter an. Beim Aufrufen von Code wird die Methode aufgerufen, und es werden konkrete Werte bereitgestellt, die für jeden Parameter als Argumente bezeichnet werden. Die Argumente müssen mit dem Parametertyp kompatibel sein, aber der argumentname (falls vorhanden), der im aufrufenden Code verwendet wird, muss nicht mit dem in der Methode definierten Parameter übereinstimmen. 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 evaluates to int.
    productC = Square(productA * 3);
}

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

Übergeben durch Referenz versus Übergeben durch Wert

Wenn eine Instanz eines Werttyps an eine Methode übergeben wird, wird die Kopie standardmäßig anstelle der Instanz selbst übergeben. Daher haben Änderungen am Argument keine Auswirkungen auf die ursprüngliche Instanz in der aufrufenden Methode. Verwenden Sie das ref Schlüsselwort, um eine Werttypinstanz anhand eines Verweises zu übergeben. Weitere Informationen finden Sie unter Übergeben von Werttypparametern.

Wenn ein Objekt eines Verweistyps an eine Methode übergeben wird, wird ein Verweis auf das Objekt übergeben. Das heißt, die Methode empfängt nicht das Objekt selbst, sondern ein Argument, das die Position des Objekts angibt. Wenn Sie ein Element des Objekts mithilfe dieses Verweises ändern, wird die Änderung auch im Argument der aufrufenden Methode widergespiegelt, selbst wenn Sie das Objekt als Wert übergeben.

Sie erstellen einen Verweistyp mithilfe des class Schlüsselworts, wie das folgende Beispiel zeigt:

public class SampleRefType
{
    public int value;
}

Wenn Sie nun ein Objekt übergeben, das auf diesem Typ basiert, an eine Methode, wird ein Verweis auf das Objekt übergeben. Im folgenden Beispiel wird ein Objekt vom Typ SampleRefType an die Methode ModifyObjectübergeben:

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 führt im Wesentlichen dieselbe Funktion wie das vorherige Beispiel aus, in dem es ein Argument nach Wert an eine Methode übergibt. Da jedoch ein Verweistyp verwendet wird, unterscheidet sich das Ergebnis. Die Änderung, die in ModifyObject am value Feld des Parameters vorgenommen wird, obj, ändert auch das value Feld des Arguments, rt, in der TestRefType Methode. Die TestRefType Methode zeigt 33 als Ausgabe an.

Weitere Informationen darüber, wie man Verweistypen als Referenz und als Wert übergibt, finden Sie unter Übergeben Reference-Type Parameter und Verweistypen.

Rückgabewerte

Methoden können einen Wert an die aufrufende Funktion (den Aufrufer) zurückgeben. Wenn der Rückgabetyp (der Typ, der vor dem Methodennamen aufgeführt ist) nicht voidangegeben ist, kann die Methode den Wert mithilfe der return Anweisung zurückgeben. Eine Anweisung mit dem 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 nach Verweis zurückgegeben werden. Werte werden anhand eines Verweises an den Aufrufer zurückgegeben, wenn das ref Schlüsselwort in der Methodensignatur verwendet wird und jedem return Schlüsselwort folgt. Die folgende Methodensignatur und Rückgabeanweisung geben beispielsweise an, dass die Methode eine Variable estDistance als Referenz zum 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 Methode nicht mehr ausgeführt, wenn sie das Ende des Codeblocks erreicht. 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 an einer beliebigen Stelle verwenden, an der ein Wert desselben Typs ausreicht. Sie können den Rückgabewert auch einer Variablen zuweisen. Die folgenden beiden Codebeispiele erreichen beispielsweise dasselbe Ziel:

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, resultzum Speichern eines Werts ist optional. Möglicherweise kann die Lesbarkeit des Codes hilfreich sein, oder es kann erforderlich sein, wenn Sie den ursprünglichen Wert des Arguments für den gesamten Bereich der Methode speichern müssen.

Um einen von einer Methode zurückgegebenen Wert zu verwenden, müssen Sie eine lokale Referenzvariable deklarieren, wenn Sie den Wert ändern möchten. Wenn die Planet.GetEstimatedDistance Methode z. B. einen Double Wert nach Verweis zurückgibt, können Sie ihn als lokale Referenzvariable mit Code wie den folgenden definieren:

ref double distance = ref Planet.GetEstimatedDistance();

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 einen besseren Stil oder einen funktionalen Wertefluss zurückgeben, jedoch ist es nicht notwendig, da C# alle Referenztypen als Wert übergibt und der Wert einer Array-Referenz der Zeiger auf das Array ist. In der Methode Msind alle Änderungen am Inhalt des Arrays durch jeden Code feststellbar, der einen Verweis auf das Array hat, 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;
        }
    }
}

Async-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 Modifizierer async kennzeichnen, können Sie den Operator await in der Methode verwenden. Wenn das Steuerelement einen Await-Ausdruck in der asynchronen Methode erreicht, kehrt das Steuerelement zum Aufrufer zurück, und der Fortschritt in 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 hat in der Regel einen Rückgabetyp von Task<TResult>, , Taskoder IAsyncEnumerable<T>void. Der Rückgabetyp void wird hauptsächlich zum Definieren von Ereignishandlern verwendet, wobei 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 abfangen, die die Methode auslöst. Eine asynchrone Methode kann jeden task-ähnlichen Rückgabetyp zurückgeben.

Im folgenden Beispiel ist DelayAsync eine asynchrone Methode mit einem Rückgabetyp von Task<TResult>. DelayAsync hat eine return Anweisung, die eine ganze Zahl zurückgibt. Daher muss die Methodendeklaration DelayAsync über einen Rückgabetyp verfügen Task<int>. Da der Rückgabetyp lautetTask<int>, erzeugt die Auswertung des await Ausdrucks DoSomethingAsync eine ganze Zahl, wie die folgende Anweisung veranschaulicht: int result = await delayTask

Die Main Methode ist ein Beispiel für eine asynchrone Methode mit einem Rückgabetyp von Task. Es geht zur DoSomethingAsync Methode und da sie mit einer einzelnen Zeile ausgedrückt ist, kann sie die async und await Schlüsselwörter weglassen. 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();.

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

Eine asynchrone Methode kann keine Referenz - oder Ausgabeparameter deklarieren, sie kann jedoch Methoden aufrufen, die über solche Parameter verfügen.

Weitere Informationen zu den asynchronen Methoden finden Sie unter Asynchrone Programmierung mit async und await und Asynchrone Rückgabetypen (C#).

Ausdruckstextdefinitionen

Es ist üblich, Methodendefinitionen zu haben, die einfach sofort das Ergebnis eines Ausdrucks zurückgeben oder die einen einzelnen Ausdruck als Methodenkörper haben. Es gibt eine Syntaxkurzform zum Definieren solcher Methoden mit =>:

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 eine asynchrone Methode ist, muss der Methodenrumpf ein Ausdruck sein (ähnlich wie bei Lambdas). Für Eigenschaften und Indexer müssen sie nur lesbar sein, und Sie verwenden nicht das get Zugriffs-Schlüsselwort.

Iteratoren

Ein Iterator führt eine benutzerdefinierte Iteration über eine Sammlung 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. Die Ausführung wird von diesem Speicherort neu gestartet, wenn der Iterator das nächste Mal aufgerufen wird.

Sie rufen einen Iterator aus Clientcode mithilfe einer Foreach-Anweisung auf.

Der Rückgabetyp eines Iterators kann IEnumerable, IEnumerable<T>, IAsyncEnumerable<T>, IEnumerator oder IEnumerator<T> sein.

Weitere Informationen finden Sie unter Iteratoren.

C#-Sprachspezifikation

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

Siehe auch