MethodenMethods

Eine Methode ist ein Codeblock, der eine Reihe von Anweisungen enthält.A method is a code block that contains a series of statements. Ein Programm bewirkt die Ausführung der Anweisungen, indem die Methode aufgerufen wird und alle erforderlichen Methodenargumente angegeben werden.A program causes the statements to be executed by calling the method and specifying any required method arguments. In C# werden alle Anweisungen im Kontext einer Methode ausgeführt.In C#, every executed instruction is performed in the context of a method. Die Methode Main ist der Einstiegspunkt jeder C#-Anwendung und wird von der Common Language Runtime (CLR) aufgerufen, wenn das Programm gestartet wird.The Main method is the entry point for every C# application and it is called by the common language runtime (CLR) when the program is started.

Hinweis

In diesem Thema werden benannte Methoden erläutert.This topic discusses named methods. Informationen über anonyme Funktionen finden Sie unter Anonyme Funktionen.For information about anonymous functions, see Anonymous Functions.

Dieses Thema enthält folgende Abschnitte:This topic contains the following sections:

MethodensignaturenMethod signatures

Methoden werden in class oder struct durch folgende Angaben deklariert:Methods are declared in a class or struct by specifying:

  • Eine optionale Zugriffsebene, z.B. public oder private.An optional access level, such as public or private. Die Standardeinstellung ist private.The default is private.
  • Optionale Modifizierer, z.B. abstract oder sealed.Optional modifiers such as abstract or sealed.
  • Der Rückgabewert oder void, wenn die Methode keinen besitzt.The return value, or void if the method has none.
  • Der Methodenname.The method name.
  • Jede Methodenparameter.Any method parameters. Methodenparameter werden in Klammern eingeschlossen und durch Kommas getrennt.Method parameters are enclosed in parentheses and are separated by commas. Leere Klammern geben an, dass für die Methode keine Parameter erforderlich sind.Empty parentheses indicate that the method requires no parameters.

Diese Teile bilden zusammen die Signatur der Methode.These parts together form the method signature.

Hinweis

Ein Rückgabetyp einer Methode ist nicht Teil der Signatur der Methode, wenn es um die Methodenüberladung geht.A return type of a method is not part of the signature of the method for the purposes of method overloading. Er ist jedoch Teil der Methodensignatur, wenn die Kompatibilität zwischen einem Delegaten und der Methode bestimmt wird, auf die dieser verweist.However, it is part of the signature of the method when determining the compatibility between a delegate and the method that it points to.

Im folgenden Beispiel wird eine Klasse mit dem Namen Motorcycle deklariert, die fünf Methoden enthält:The following example defines a class named Motorcycle that contains five methods:

using System;

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

Beachten Sie, dass die Motorcycle-Klasse eine überladene Methode, Drive, enthält.Note that the Motorcycle class includes an overloaded method, Drive. Zwei Methoden haben denselben Namen, müssen aber durch ihre Parametertypen unterschieden werden.Two methods have the same name, but must be differentiated by their parameter types.

MethodenaufrufMethod invocation

Methoden können entweder instance oder static sein.Methods can be either instance or static. Das Aufrufen einer Instanzmethode erfordert, dass Sie ein Objekt instanziieren und die Methode an diesem Objekt aufrufen; eine Instanzmethode funktioniert in dieser Instanz und ihren Daten.Invoking an instance method requires that you instantiate an object and call the method on that object; an instance method operates on that instance and its data. Sie rufen eine statische Methode auf, indem Sie auf den Namen des Typs verweisen, zu der die Methode gehört; statische Methoden funktionieren nicht in Instanzdaten.You invoke a static method by referencing the name of the type to which the method belongs; static methods operate do not operate on instance data. Bei dem Versuch eine statische Methode über eine Objektinstanz aufzurufen, wird ein Compilerfehler erzeugt.Attempting to call a static method through an object instance generates a compiler error.

Das Aufrufen einer Methode ähnelt dem Zugreifen auf ein Feld.Calling a method is like accessing a field. Fügen Sie nach dem Objektnamen (wenn Sie eine Instanzmethode aufrufen) oder dem Typnamen (beim Aufrufen einer static-Methode) einen Punkt, den Methodennamen und Klammern hinzu.After the object name (if you are calling an instance method) or the type name (if you are calling a static method), add a period, the name of the method, and parentheses. Argumente werden innerhalb der Klammern aufgelistet und durch Kommas getrennt.Arguments are listed within the parentheses, and are separated by commas.

Die Methodendefinition gibt die Namen und Typen aller ggf. erforderlichen Parameter an.The method definition specifies the names and types of any parameters that are required. Wenn ein Aufrufer die Methode aufruft, werden für jeden Parameter konkrete Werte bereitgestellt, die als Argumente bezeichnet werden.When a caller invokes the method, it provides concrete values, called arguments, for each parameter. Die Argumente müssen mit dem Parametertyp kompatibel sein, aber der Name des Arguments (sofern im aufzurufenden Code einer verwendet wird) muss nicht mit dem in der Methode definierten Parameternamen identisch sein.The arguments must be compatible with the parameter type, but the argument name, if one is used in the calling code, does not have to be the same as the parameter named defined in the method. Im folgenden Beispiel enthält die Square-Methode einen einzelnen Parameter vom Typ int mit dem Namen i.In the following example, the Square method includes a single parameter of type int named i. Der erste Methodenaufruf übergibt der Square-Methode eine Variable vom Typ int mit dem Namen num. Der zweite übergibt eine numerische Konstante und der dritte einen Ausdruck.The first method call passes the Square method a variable of type int named num; the second, a numeric constant; and the third, an expression.

public class Example
{
   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 evaulates 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;
   }
}

Die häufigste Form des Methodenaufrufs verwendete Positionsargumente. Die Argumente werden in der gleichen Reihenfolge wie Methodenparameter bereitgestellt.The most common form of method invocation used positional arguments; it supplies arguments in the same order as method parameters. Die Methoden der Motorcycle-Klasse können deshalb wie im folgenden Beispiel aufgerufen werden.The methods of the Motorcycle class can therefore be called as in the following example. Der Aufruf der Drive-Methode enthält z.B. zwei Argumente, die den beiden Parametern in der Syntax der Methode entsprechen.The call to the Drive method, for example, includes two arguments that correspond to the two parameters in the method's syntax. Das erste Argument wird der Wert des miles-Parameters, das zweite wird der Wert des speed-Parameters.The first becomes the value of the miles parameter, the second the value of the speed parameter.

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

Sie können auch benannte Argumente anstatt Positionsargumente verwenden, wenn Sie eine Methode aufrufen.You can also used named arguments instead of positional arguments when invoking a method. Wenn Sie benannte Argumente verwenden, geben Sie den Parameternamen, gefolgt von einem Doppelpunkt („:“), und das Argument an.When using named arguments, you specify the parameter name followed by a colon (":") and the argument. Argumente können für diese Methode in beliebiger Reihenfolge erscheinen, solange alle benötigen Argumente vorhanden sind.Arguments to the method can appear in any order, as long as all required arguments are present. Im folgenden Beispiel werden die benannten Argumente zum Aufrufen der TestMotorcycle.Drive-Methode verwendet.The following example uses named arguments to invoke the TestMotorcycle.Drive method. In diesem Beispiel werden die benannten Argumente in umgekehrter Reihenfolge aus der Parameterliste der Methode übergeben.In this example, the named arguments are passed in the opposite order from the method's parameter list.

using System;

class TestMotorcycle : Motorcycle
{
   public override int Drive(int miles, int speed)
   {
      return (int) Math.Round( ((double)miles) / speed, 0);
   }

   public override double GetTopSpeed()
   {
      return 108.4;
   }

   static void Main()
   {
      
      TestMotorcycle moto = new TestMotorcycle();
      moto.StartEngine();
      moto.AddGas(15);
      var travelTime = moto.Drive(speed: 60, miles: 170);
      Console.WriteLine("Travel time: approx. {0} hours", travelTime);            
   }
}
// The example displays the following output:
//      Travel time: approx. 3 hours

Sie können eine Methode aufrufen, indem Sie sowohl Positionsargumente als auch benannte Argumente verwenden.You can invoke a method using both positional arguments and named arguments. Auf ein benanntes Argument kann jedoch kein Positionsargument folgen.However, a positional argument cannot follow a named argument. Im folgenden Beispiel wird die TestMotorcycle.Drive-Methode des vorherigen Beispiels aufgerufen, indem jeweils ein Positionsargument und ein benanntes Argument verwendet wird.The following example invokes the TestMotorcycle.Drive method from the previous example using one positional argument and one named argument.

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

##Geerbte und überschriebene MethodenInherited and overridden methods ##

Zusätzlich zu den Elementen, die ausdrücklich in einem Typ definiert werden, erbt ein Typ Member, die in seiner Basisklasse definiert wurden.In addition to the members that are explicitly defined in a type, a type inherits members defined in its base classes. Da alle Typen im System verwalteten Typs direkt oder indirekt von erben die Object Klasse erben, alle Typen seiner Elemente, wie z. B. Equals(Object), GetType(), und ToString().Since all types in the managed type system inherit directly or indirectly from the Object class, all types inherit its members, such as Equals(Object), GetType(), and ToString(). Im folgenden Beispiel wird eine Person-Klasse definiert, zwei Person-Objekte instanziiert, und es wird die Person.Equals-Methode aufgerufen, um zu bestimmen, ob die zwei Objekte gleich sind.The following example defines a Person class, instantiates two Person objects, and calls the Person.Equals method to determine whether the two objects are equal. Jedoch ist die Equals-Methode nicht in der Person-Klasse definiert; sie wird von Object vererbt.The Equals method, however, is not defined in the Person class; it is inherited from Object.

using System;

public class Person
{
   public String FirstName;
}

public class Example
{
   public static void Main()
   {
      var p1 = new Person();
      p1.FirstName = "John";
      var p2 = new Person();
      p2.FirstName = "John";
      Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
   }
}
// The example displays the following output:
//      p1 = p2: False

Typen können geerbte Member überschreiben, indem das Schlüsselwort override verwendet und eine Implementierung für die überschriebene Methode bereitgestellt wird.Types can override inherited members by using the override keyword and providing an implementation for the overridden method. Die Signatur der Methode muss mit der die überschriebene Methode identisch sein.The method signature must be the same as that of the overridden method. Im folgende Beispiel ähnelt der vorherigen Abfrage, mit dem Unterschied, dass es überschreibt die Equals(Object) Methode.The following example is like the previous one, except that it overrides the Equals(Object) method. (Sie überschreibt auch die GetHashCode()-Methode, da die zwei Methoden konsistente Ergebnisse bereitstellen sollen)(It also overrides the GetHashCode() method, since the two methods are intended to provide consistent results.)

using System;

public class Person
{
   public String FirstName;

   public override bool Equals(object obj)
   {
      var p2 = obj as Person; 
      if (p2 == null)
         return false;
      else
         return FirstName.Equals(p2.FirstName);
   }

   public override int GetHashCode()
   {
      return FirstName.GetHashCode();
   } 
}

public class Example
{
   public static void Main()
   {
      var p1 = new Person();
      p1.FirstName = "John";
      var p2 = new Person();
      p2.FirstName = "John";
      Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
   }
}
// The example displays the following output:
//      p1 = p2: True

Übergeben von ParameternPassing parameters

Typen in C# sind entweder Werttypen oder Verweistypen.Types in C# are either value types or reference types. Eine Liste der integrierten Werttypen finden Sie unter Typen und Variablen.For a list of built-in value types, see Types and variables. Sowohl Werttypen als auch Verweistypen werden standardmäßig als Wert an eine Methode übergeben.By default, both value types and reference types are passed to a method by value.

Übergeben von Parametern als WertPassing parameters by value

Wenn ein Werttyp an eine Methode als Wert übergeben wird, wird anstelle des eigentlichen Objekts standardmäßig eine Kopie übergeben.When a value type is passed to a method by value, a copy of the object instead of the object itself is passed to the method. Aus diesem Grund haben Änderungen am Objekt in der aufgerufenen Methode keine Auswirkung auf das ursprüngliche Objekt, wenn das Steuerelement an den Aufrufer zurückgegeben wird.Therefore, changes to the object in the called method have no effect on the original object when control returns to the caller.

Im folgenden Beispiel wird ein Werttyp als Wert an eine Methode übergeben, und die aufgerufene Methode versucht, den Wert des Werttyps zu ändern.The following example passes a value type to a method by value, and the called method attempts to change the value type's value. Es definiert eine Variable des Typs int, die ein Werttyp ist, initialisiert seine Werte auf 20 und übergibt ihn an eine Methode mit dem Namen ModifyValue, die den Wert der Variable in 30 ändert.It defines a variable of type int, which is a value type, initializes its value to 20, and passes it to a method named ModifyValue that changes the variable's value to 30. Wenn die Methode zurückgegeben wird, bleibt der Wert der Variable jedoch unverändert.When the method returns, however, the variable's value remains unchanged.

using System;

public class Example
{
   public static void Main()
   {
      int 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

Wenn ein Objekt eines Verweistyps als Wert an eine Methode übergeben wird, wird ein Verweis als Wert auf das Objekt übergeben.When an object of a reference type is passed to a method by value, a reference to the object is passed by value. Das heißt, die Methode erhält nicht das Objekt selbst, sondern ein Argument, das den Speicherort des Objekts angibt.That is, the method receives not the object itself, but an argument that indicates the location of the object. Wenn Sie einen Member des Objekts unter Verwendung dieses Verweises ändern, wird die Änderung im Objekt berücksichtigt, wenn das Steuerelement der aufrufenden Methode zurückgegeben wird.If you change a member of the object by using this reference, the change is reflected in the object when control returns to the calling method. Jedoch hat das Ersetzen des Objekts, das an die Methode übergeben wird, keine Auswirkung auf das ursprüngliche Objekt, wenn das Steuerelement dem Aufrufer zurückgegeben wird.However, replacing the object passed to the method has no effect on the original object when control returns to the caller.

Im folgenden Beispiel wird eine Klasse (die ein Verweistyp ist) mit dem Namen SampleRefType definiert.The following example defines a class (which is a reference type) named SampleRefType. Sie instanziiert ein SampleRefType-Objekt, weist seinem value-Feld 44 zu, und übergibt das Objekt der ModifyObject-Methode.It instantiates a SampleRefType object, assigns 44 to its value field, and passes the object to the ModifyObject method. Dieses Beispiel entspricht im Wesentlichen dem vorherigen Beispiel und übergibt ein Argument als Wert an eine Methode.This example does essentially the same thing as the previous example -- it passes an argument by value to a method. Da jedoch ein Verweistyp verwendet wird, unterscheidet sich das Ergebnis.But because a reference type is used, the result is different. Die Änderung, die in ModifyObject am obj.value-Feld vorgenommen wurden, ändern auch das value-Feld des Arguments rt in der Main-Methode auf 33, wie die Ausgabe des Beispiels zeigt.The modification that is made in ModifyObject to the obj.value field also changes the value field of the argument, rt, in the Main method to 33, as the output from the example shows.

using System;

public class SampleRefType
{
    public int value;
}

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

Übergeben von Parametern durch einen VerweisPassing parameters by reference

Sie übergeben einen Parameter durch einen Verweis, wenn Sie den Wert eines Arguments in einer Methode ändern möchten und diese Änderung berücksichtigen wollen, wenn das Steuerelement der aufrufenden Methode zurückgegeben wird.You pass a parameter by reference when you want to change the value of an argument in a method and want to refect that change when control returns to the calling method. Verwenden Sie das Schlüsselwort ref oder out, um einen Parameter als Verweis zu übergeben.To pass a parameter by reference, you use the ref or out keyword.

Das folgende Beispiel ist identisch mit dem vorherigen Beispiel, außer dass der Wert durch einen Verweis an die ModifyValue-Methode übergeben wird.The following example is identical to the previous one, except the value is passed by reference to the ModifyValue method. Wenn der Wert des Parameters in der ModifyValue-Methode verändert wird, wird die Wertänderung berücksichtigt, wenn das Steuerelement dem Aufrufer zurückgegeben wird.When the value of the parameter is modified in the ModifyValue method, the change in value is reflected when control returns to the caller.

using System;

public class Example
{
   public static void Main()
   {
      int value = 20;
      Console.WriteLine("In Main, value = {0}", value);
      ModifyValue(ref value);
      Console.WriteLine("Back in Main, value = {0}", value);
   }

   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

Ein häufiges Muster, das von ref-Parametern verwendet wird, umfasst das Tauschen der Werte der Variablen.A common pattern that uses by ref parameters involves swapping the values of variables. Sie übergeben durch einen Verweis zwei Variablen an eine Methode, und die Methode tauscht deren Inhalte.You pass two variables to a method by reference, and the method swaps their contents. Im folgenden Beispiel werden ganzzahlige Werte getauscht.The following example swaps integer values.

using System;

public class Example
{
   static void Main()
   {
      int i = 2, j = 3;
      System.Console.WriteLine("i = {0}  j = {1}" , i, j);

      Swap(ref i, ref j);

      System.Console.WriteLine("i = {0}  j = {1}" , i, j);
   }

   static void Swap(ref int x, ref int y)
   {
      int temp = x;
      x = y;
      y = temp;
   }   
}
// The example displays the following output:
//      i = 2  j = 3
//      i = 3  j = 2

Durch das Übergeben eines Verweistyp-Parameters können Sie den eigentlichen Wert des Verweises anstatt den Wert der einzelnen Elemente oder Felder ändern.Passing a reference-type parameter allows you to change the value of the reference itself, rather than the value of its individual elements or fields.

ParameterarraysParameter arrays

Manchmal ist die Voraussetzung, dass Sie die genaue Anzahl von Argumenten für Ihre Methode angeben, restriktiv.Sometimes, the requirement that you specify the exact number of arguments to your method is restrictive. Mithilfe des Schlüsselworts params wird angegeben, dass ein Parameter ein Parameterarray ist, und Sie können Ihre Methode mit einer variablen Anzahl von Argumenten aufrufen.By using the params keyword to indicate that a parameter is a parameter array, you allow your method to be called with a variable number of arguments. Der mit dem Schlüsselwort params gekennzeichnete Parameter muss ein Arraytyp sein, und er muss der letzte Parameter in der Parameterliste der Methode sein.The parameter tagged with the params keyword must must be an array type, and it must be the last parameter in the method's parameter list.

Ein Aufrufer kann anschließend die Methode auf drei verschiedene Arten aufrufen:A caller can then invoke the method in either of three ways:

  • Durch das Übergeben eines Arrays des entsprechenden Typs, der die gewünschte Anzahl von Elementen enthältBy passing an array of the appropriate type that contains the desired number of elements.
  • Durch das Übergeben einer mit Komma getrennten Liste eines einzelnen Arguments des entsprechenden Typs der MethodeBy passing a comma-separated list of individual arguments of the appropriate type to the method.
  • Durch keine Bereitstellung eines Arguments für das ParameterarrayBy not providing an argument to the parameter array.

Im folgenden Beispiel wird eine Methode mit dem Namen DoStringOperation definiert, die den Zeichenfolgevorgang ausführt, der von dessen erstem Parameter – einem StringOperation-Enumerationsmember – angegeben wurde.The following example defines a method named DoStringOperation that performs the string operation specified by its first parameter, a StringOperation enumeration member. Die Zeichenfolge, von der der Vorgang ausgeführt wird, wird durch ein Parameterarray definiert.The strings upon which it is to perform the operation are defined by a parameter array. Die Main-Methode zeigt alle drei Möglichkeiten, um die Methode aufzurufen.The Main method illustrates all three ways of invoking the method. Beachten Sie, dass die mit Schlüsselwort params gekennzeichnete Methode auf den Fall vorbereitet werden muss, in dem kein Argument für das Parameterarray bereitgestellt wird, sodass sein Wert null entspricht.Note that the method tagged with the params keyword must be prepared to handle the case in which no argument is supplied for the parameter array, so that its value is null.

using System;

class Example 
{
    static void Main() 
    {
        int[] arr = {1, 4, 5};
        Console.WriteLine("In Main, array has {0} elements and starts with {1}",
                          arr.Length, arr[0]);

        Change(ref arr);
        Console.WriteLine("Back in Main, array has {0} elements and starts with {1}",
                          arr.Length, arr[0]);
    }

    static void Change(ref int[] arr)
    {
        // Both of the following changes will affect the original variables:
        arr = new int[5] {-9, -7, -5, -3, -1};
        Console.WriteLine("In Change, array has {0} elements and starts with {1}",
                          arr.Length, arr[0]);
    }
}
// The example displays the following output:
//        In Main, array has 3 elements and starts with 1
//        In Change, array has 5 elements and starts with -9
//        Back in Main, array has 5 elements and starts with -9

Optionale Parameter und ArgumenteOptional parameters and arguments

Eine Methodendefinition kann angeben, dass seine Parameter erforderlich oder optional sind.A method definition can specify that its parameters are required or that they are optional. Parameter sind standardmäßig erforderlich.By default, parameters are required. Optionale Parameter werden einschließlich des Standardwerts des Parameters in der Methodendefinition angegeben.Optional parameters are specified by including the parameter's default value in the method definition. Wird die Methode aufgerufen, wenn kein Argument für einen optionalen Parameter angegeben wird, wird stattdessen der Standardwert verwendet.When the method is called, if no argument is supplied for an optional parameter, the default value is used instead.

Der Standardwert des Parameters muss von einer der folgenden Ausdrucksarten zugewiesen werden:The parameter's default value must be assigned by one of the following kinds of expressions:

  • Eine Konstante, z.B. eine Zeichenfolgenliteral oder eine ZahlA constant, such as a literal string or number.
  • Ein Ausdruck in Form von new ValType, wobei ValType ein Werttyp ist.An expression of the form new ValType, where ValType is a value type. Beachten Sie, dass dies den impliziten Standardkonstruktor des Werttyps aufruft, der eigentlich kein Member des Typs ist.Note that this invokes the value type's implicit default constructor, which is not an actual member of the type.
  • Ein Ausdruck in Form von default(ValType), wobei ValType ein Werttyp istAn expression of the form default(ValType), where ValType is a value type.

Wenn eine Methode erforderliche und optionale Parameter enthält, werden optionale Parameter nach allen benötigten Parametern am Ende der Parameterliste definiert.If a method includes both required and optional parameters, optional parameters are defined at the end of the parameter list, after all required parameters.

Im folgenden Beispiel wird eine ExampleMethod-Methode definiert, die aus einem erforderlichen und zwei optionalen Parametern besteht.The following example defines a method, ExampleMethod, that has one required and two optional parameters.

using System;

public class Options
{
   public void ExampleMethod(int required, int optionalInt = default(int),
                             string description = "Optional Description")
   {
      Console.WriteLine("{0}: {1} + {2} = {3}", description, required, 
                        optionalInt, required + optionalInt);
   }
}

Wenn eine Methode mit mehreren optionalen Argumenten mithilfe von Positionsargumenten aufgerufen wird, muss der Aufrufer ein Argument für alle optionalen Parameter, vom ersten bis zum letzten, bereitstellen, für die ein Argument bereitgestellt wird.If a method with multiple optional arguments is invoked using positional arguments, the caller must supply an argument for all optional parameters from the first one to the last one for which an argument is supplied. Bei der ExampleMethod-Methode muss der Parameter z.B. auch ein Argument für den description-Parameter bereitstellen, wenn er ein Argument für den optionalInt-Parameter bereitstellt.In the case of the ExampleMethod method, for example, if the caller supplies an argument for the description parameter, it must also supply one for the optionalInt parameter. opt.ExampleMethod(2, 2, "Addition of 2 and 2"); ist ein gültiger Methodenaufruf; opt.ExampleMethod(2, , "Addition of 2 and 0); erzeugt einen Compilerfehler: „Argument fehlt“.opt.ExampleMethod(2, 2, "Addition of 2 and 2"); is a valid method call; opt.ExampleMethod(2, , "Addition of 2 and 0); generates an "Argument missing" compiler error.

Wenn eine Methode durch ein benanntes Argument oder einer Mischung aus benannten und Positionsargumenten aufgerufen wird, kann der Aufrufer Argumente auslassen, die dem letzten Positionsargument im Methodenaufruf folgen.If a method is called using named arguments or a combination of positional and named arguments, the caller can omit any arguments that follow the last positional argument in the method call.

Im folgenden Beispiel wird die ExampleMethod-Methode dreimal aufgerufen.The following example calls the ExampleMethod method three times. Die ersten zwei Methodenaufrufe verwenden Positionsargumente.The first two method calls use positional arguments. Der erste Methodenaufruf lässt beide optionale Argumente aus, während der Zweite das letzte Argument auslässt.The first omits both optional arguments, while the second omits the last argument. Der dritte Methodenaufruf stellt für die benötigten Parameter ein Positionsargument bereit, verwendet aber ein benanntes Argument, um einen Wert für den description-Parameter bereitzustellen, während das optionalInt-Argument ausgelassen wird.The third method call supplies a positional argument for the required parameter, but uses a named argument to supply a value to the description parameter while omitting the optionalInt argument.

public class Example
{
   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:
//      Optional Description: 10 + 0 = 10
//      Optional Description: 10 + 2 = 12
//      Addition with zero:: 12 + 0 = 12

Die Verwendung von zwei optionalen Parametern wirkt sich auf die Überladungsauflösung aus, oder die Art und Weise, mit der der C#-Compiler bestimmt, welche besondere Überladung von einem Methodenaufruf wie folgt aufgerufen werden sollte:The use of optional parameters affects overload resolution, or the way in which the C# compiler determines which particular overload should be invoked by a method call, as follows:

  • Eine Methode, ein Indexer oder ein Konstruktor ist ein Kandidat für die Ausführung, wenn jeder der Parameter entweder optional ist oder über Namen oder Position auf ein einzelnes Argument in der aufrufenden Anweisung reagiert. Dieses Argument kann in dem Typ des Parameters konvertiert werden.A method, indexer, or constructor is a candidate for execution if each of its parameters either is optional or corresponds, by name or by position, to a single argument in the calling statement, and that argument can be converted to the type of the parameter.
  • Wenn mehr als ein Kandidat gefunden wird, werden die Regeln der Überladungsauflösung als bevorzugte Konvertierungen auf die Argumente angewandt, die ausdrücklich angegeben sind.If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Ausgelassene Argumente für optionale Parameter werden ignoriert.Omitted arguments for optional parameters are ignored.
  • Wenn zwei Kandidaten gleich gut geeignet sind, wird ein Kandidat bevorzugt, der keine optionalen Parameter besitzt, für die Argumente im Aufruf ausgelassen wurden.If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. Dies ist die Folge einer allgemeinen Präferenz bei der Überladungsauflösung für Kandidaten, die weniger Parameter besitzen.This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

RückgabewertReturn values

Methoden können einen Wert an die aufrufende Funktion (den Aufrufer) zurückgeben.Methods can return a value to the caller. Wenn der Rückgabetyp (der vor dem Methodennamen aufgeführte Typ) nicht void ist, kann die Methode den Wert mithilfe des return-Schlüsselworts zurückgeben.If the return type (the type listed before the method name) is not void, the method can return the value by using the return keyword. Eine Anweisung mit dem Schlüsselwort return, gefolgt von einem Wert, der dem Rückgabetyp entspricht, gibt diesen Wert an den Methodenaufrufer zurück.A statement with the return keyword followed by a variable, constant, or expression that matches the return type will return that value to the method caller. Methoden mit einem anderen Rückgabetyp als „void“ müssen das return -Schlüsselwort verwenden, um einen Wert zurückzugeben.Methods with a non-void return type are required to use the return keyword to return a value. Das return -Schlüsselwort beendet außerdem die Ausführung der Methode.The return keyword also stops the execution of the method.

Wenn der Rückgabetyp voidist, ist eine return -Anweisung ohne Wert immer noch nützlich, um die Ausführung der Methode zu beenden.If the return type is void, a return statement without a value is still useful to stop the execution of the method. Ohne das return -Schlüsselwort wird die Ausführung der Methode beendet, wenn das Ende des Codeblocks erreicht ist.Without the return keyword, the method will stop executing when it reaches the end of the code block.

Die folgenden beiden Methoden verwenden z. B. das return -Schlüsselwort, um ganze Zahlen zurückzugeben:For example, these two methods use the return keyword to return integers:

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.To use a value returned from a method, the calling method can use the method call itself anywhere a value of the same type would be sufficient. Sie können den Rückgabewert auch einer Variablen zuweisen.You can also assign the return value to a variable. Beispielsweise wird mit den folgenden beiden Codebeispiele das gleiche Ergebnis erzielt:For example, the following two code examples accomplish the same goal:

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.Using a local variable, in this case, result, to store a value is 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.It may help the readability of the code, or it may be necessary if you need to store the original value of the argument for the entire scope of the method.

Manchmal möchten Sie, dass Ihre Methode mehr als einen Wert zurückgibt.Sometimes, you want your method to return more than a single value. Ab mit C#-7.0 können Sie dies einfach mithilfe von Tupeltypen und Tupelliteralen erledigen.Starting with C# 7.0, you can do this easily by using tuple types and tuple literals. Der Tupeltyp definiert die Datentypen der Elemente des Tupels.The tuple type defines the data types of the tuple's elements. Tupelliterale stellen die tatsächlichen Werte des zurückgegebenen Tupels bereit.Tuple literals provide the actual values of the returned tuple. Im folgenden Beispiel (string, string, string, int) definiert die Tupeltyp, der von zurückgegeben wird die GetPersonalInfo Methode.In the following example, (string, string, string, int) defines the tuple type that is returned by the GetPersonalInfo method. Der (per.FirstName, per.MiddleName, per.LastName, per.Age)-Ausdruck ist das Tupelliteral. Die Methode gibt den ersten, mittleren und letzten Namen zusammen mit dem Alter eines PersonInfo-Objekts zurück.The expression (per.FirstName, per.MiddleName, per.LastName, per.Age) is the tuple literal; the method returns the first, middle, and last name, along with the age, of a PersonInfo object.

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

Der Aufrufer kann anschließend das zurückgegebene Tupel mit Code wie dem folgenden verwenden:The caller can then consume the returned tuple with code like the following:

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

Namen können auch den Tupelelementen in der Typdefinition des Tupels zugewiesen werden.Names can also be assigned to the tuple elements in the tuple type definition. Das folgende Beispiel zeigt eine alternative Version der GetPersonalInfo-Methode, die benannte Elemente verwendet:The following example shows an alternate version of the GetPersonalInfo method that uses named elements:

public (string FName, string MName, string LName, int Age) GetPersonalInfo(string id)
{
    PersonInfo per = PersonInfo.RetrieveInfoById(id);
    if (per != null)
       return (per.FirstName, per.MiddleName, per.LastName, per.Age);
    else
       return null;
}

Der vorherige Aufruf der GetPersonInfo-Methode kann anschließend wie folgt geändert werden:The previous call to the GetPersonInfo method can then be modified as follows:

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

Wenn eine Methode einem Array als Argument übergeben wird und den Wert der einzelnen Elemente ändert, ist es nicht erforderlich, dass die Methode das Array zurückgibt, obwohl Sie sich entscheiden könnten, dies für den funktionalen Fluss von Werten oder zu stilistischen Zwecken zu tun.If a method is passed an array as an argument and modifies the value of individual elements, it is not necessary for the method to return the array, although you may choose to do so for good style or functional flow of values. Das liegt daran, dass C# alle Verweistypen als Wert übergibt und der Wert eines Arrayverweises der Zeiger auf das Array ist.This is because C# passes all reference types by value, and the value of an array reference is the pointer to the array. Im folgenden Beispiel sind Änderungen an den Inhalten des values-Arrays, die in der DoubleValues-Methode ausgeführt werden, von jedem Code beobachtbar, der einen Verweis auf das Array hat.In the following example, changes to the contents of the values array that are made in the DoubleValues method are observable by any code that has a reference to the array.



using System;

public class Example
{
   static void Main(string[] args)  
   {  
      int[] values = { 2, 4, 6, 8 };
      DoubleValues(values);
      foreach (var value in values)
         Console.Write("{0}  ", value);
   }  
  
   public static void DoubleValues(int[] arr)
   {
      for (int ctr = 0; ctr <= arr.GetUpperBound(0); ctr++)
         arr[ctr] = arr[ctr] * 2;
   }
}
// The example displays the following output:
//       4  8  12  16

ErweiterungsmethodenExtension methods

Es gibt normalerweise zwei Möglichkeiten, einem vorhandenen Typ eine Methode hinzuzufügen:Ordinarily, there are two ways to add a method to an existing type:

  • Ändern Sie den Quellcode für diesen Typ.Modify the source code for that type. Sie können dies natürlich nicht tun, wenn Sie nicht den Quellcode des Typs besitzen.You cannot do this, of course, if you do not own the type's source code. Dies wird zudem eine bahnbrechende Änderung, wenn Sie auch private Datenfelder zur Unterstützung der Methode hinzufügen.And this becomes a breaking change if you also add any private data fields to support the method.
  • Definieren Sie die neue Methode in einer abgeleiteten Klasse.Define the new method in a derived class. Eine Methode kann nicht auf diese Weise für andere Typen wie Strukturen oder Enumerationen mithilfe von Vererbung hinzugefügt werden.A method cannot be added in this way using inheritance for other types, such as structures and enumerations. Sie kann auch nicht verwendet werden, um einer versiegelten Klasse eine Methode „hinzuzufügen“.Nor can it be used to "add" a method to a sealed class.

Erweiterungsmethoden lassen Sie eine Methode einem vorhanden Typ „hinzufügen“, ohne den eigentlichen Typ zu verändern oder die neue Methode in einem geerbten Typ zu implementieren.Extension methods let you "add" a method to an existing type without modifying the type itself or implementing the new method in an inherited type. Die Erweiterungsmethode muss sich auch nicht im gleichen Assembly wie der Typ befinden, den es erweitert.The extension method also does not have to reside in the same assembly as the type it extends. Sie rufen eine Erweiterungsmethode auf, als ob es sich um einen definierten Member eines Typs handele.You call an extension method as if it were a defined member of a type.

Weitere Informationen finden Sie unter Erweiterungsmethoden.For more information, see Extension Methods.

Asynchrone MethodenAsync Methods

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.By using the async feature, you can invoke asynchronous methods without using explicit callbacks or manually splitting your code across multiple methods or lambda expressions.

Wenn Sie eine Methode mit dem Modifizierer async kennzeichnen, können Sie den Operator await in der Methode verwenden.If you mark a method with the async modifier, you can use the await operator in the method. Wenn ein await-Ausdruck in der asynchronen Methode erreicht wird, wird die Steuerung an den Aufrufer zurückgegeben, wenn die erwartete Aufgabe nicht fertig ist, und die Ausführung der Methode mit dem Schlüsselwort await wird angehalten, bis die erwartete Aufgabe abgeschlossen ist.When control reaches an await expression in the async method, control returns to the caller if the awaited task is not completed, and progress in the method with the await keyword is suspended until the awaited task completes. Wenn die Aufgabe abgeschlossen ist, kann die Ausführung in der Methode fortgesetzt werden.When the task is complete, execution can resume in the method.

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.An async method returns to the caller when either it encounters the first awaited object that’s not yet complete or it gets to the end of the async method, whichever occurs first.

Eine asynchrone Methode kann den Rückgabetyp haben Task<TResult>, Task, oder void.An async method can have a return type of Task<TResult>, Task, or void. Der Rückgabetyp void wird hauptsächlich zum Definieren von Ereignishandlern verwendet, wobei ein void-Rückgabetyp erforderlich ist.The void return type is used primarily to define event handlers, where a void return type is required. 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.An async method that returns void can't be awaited, and the caller of a void-returning method can't catch exceptions that the method throws. Mit der Veröffentlichung von C# 7 wird es diese Einschränkung gelockert, damit eine asynchrone Methode jeden aufgabenähnlichen Typ zurückgeben kann.C# 7, when it is released, will ease this restriction to allow an async method to return any task-like type.

Im folgenden Beispiel ist DelayAsync eine asynchrone Methode, die eine Rückgabeanweisung besitzt, die eine ganze Zahl zurückgibt.In the following example, DelayAsync is an async method that has a return statement that returns an integer. Da es sich um eine async-Methode handelt, muss die Methodendeklaration einen Task<int>-Rückgabetyp haben.Because it is an async method, its method declaration must have a return type of Task<int>. Da der Rückgabetyp Task<int> ist, ergibt die Auswertung des await-Ausdrucks in DoSomethingAsync eine ganze Zahl, wie die folgende int result = await delayTask-Anweisung veranschaulicht.Because the return type is Task<int>, the evaluation of the await expression in DoSomethingAsync produces an integer, as the following int result = await delayTask statement demonstrates.

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

public class Example
{
    // This Click event is marked with the async modifier.
    public static void Main()
    {
       DoSomethingAsync().Wait();
    }

    private static async Task DoSomethingAsync()
    {
        int result = await DelayAsync();
        Console.WriteLine("Result: " + result);
    }

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

    // Output:
    //  Result: 5
}
// The example displays the following output:
//        Result: 5

Mit einer asynchronen Methode können keine ref- oder out-Parameter deklariert, jedoch Methoden aufgerufen werden, die solche Parameter aufweisen.An async method can't declare any ref or out parameters, but it can call methods that have such parameters.

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.For more information about async methods, see Asynchronous Programming with Async and Await, Control Flow in Async Programs, and Async Return Types.

AusdruckskörpermemberExpression-bodied members

Es gibt häufig Methodendefinitionen, die einfach direkt das Ergebnis eines Ausdrucks zurückgeben oder eine einzige Anweisung als Text der Methode aufweisen.It is common to have method definitions that simply return immediately with the result of an expression, or that have a single statement as the body of the method. Es ist eine Syntaxabkürzung zur Definition solcher Methoden mithilfe von =>verfügbar:There is a syntax shortcut for defining such methods using =>:

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).If the method returns void or is an async method, the body of the method must be a statement expression (same as with lambdas). Eigenschaften und Indexer müssen schreibgeschützt sein. Verwenden Sie darüber hinaus nicht das get-Accessorschlüsselwort.For properties and indexers, they must be read-only, and you do not use the get accessor keyword.

IteratorenIterators

Ein Iterator führt eine benutzerdefinierte Iteration durch eine Auflistung durch, z. B. eine Liste oder ein Array.An iterator performs a custom iteration over a collection, such as a list or an array. Ein Iterator verwendet die Anweisung yield return, um jedes Element einzeln nacheinander zurückzugeben.An iterator uses the yield return statement to return each element one at a time. Wenn eine yield return-Anweisung erreicht wird, wird die aktuelle Position gespeichert, sodass der Aufrufer das nächste Element in der Sequenz anfordern kann.When a yield return statement is reached, the current location is remembered so that the caller can request the next element in the sequence.

Der Rückgabetyp eines Iterators kann IEnumerable, IEnumerable<T>, IEnumeratoroder IEnumerator<T>sein.The return type of an iterator can be IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>.

Weitere Informationen finden Sie unter Iteratoren.For more information, see Iterators.

Siehe auchSee also

Zugriffsmodifizierer Access Modifiers
Statische Klassen und statische Klassenmember Static Classes and Static Class Members
Vererbung Inheritance
Abstrakte und versiegelte Klassen und Klassenmember Abstract and Sealed Classes and Class Members
params params
out out
ref ref
Übergeben von ParameternPassing Parameters