Modifizierer für in-Parameter (C#-Verweis)in parameter modifier (C# Reference)

Das Schlüsselwort in bewirkt, dass Argumente per Verweis übergeben werden.The in keyword causes arguments to be passed by reference. Es verhält sich ähnlich wie die Schlüsselwörter ref und out. Der einzige Unterschied besteht darin, dass in-Argumente nicht von der aufgerufenen Methode modifiziert werden können.It is like the ref or out keywords, except that in arguments cannot be modified by the called method. Obwohl ref-Argumente modifiziert werden können, müssen out-Argumente von der aufgerufenen Methode geändert werden. Die Änderungen werden im Aufrufkontext angezeigt.Whereas ref arguments may be modified, out arguments must be modified by the called method, and those modifications are observable in the calling context.

int readonlyArgument = 44;
InArgExample(readonlyArgument);
Console.WriteLine(readonlyArgument);     // value is still 44

void InArgExample(in int number)
{
    // Uncomment the following line to see error CS8331
    //number = 19;
}

Das vorausgehende Beispiel veranschaulicht, dass der in-Modifizierer an der Aufrufstelle normalerweise nicht benötigt wird.The preceding example demonstrates that the in modifier is usually unnecessary at the call site. Er ist nur in der Methodendeklaration erforderlich.It is only required in the method declaration.

Hinweis

Das in-Schlüsselwort kann ebenfalls mit einem generischen Typparameter verwendet werden, um als der Bestandteil einer foreach-Anweisung oder einer join-Klausel in einer LINQ-Abfrage anzugeben, dass der Typparameter kontravariant ist.The in keyword can also be used with a generic type parameter to specify that the type parameter is contravariant, as part of a foreach statement, or as part of a join clause in a LINQ query. Weitere Informationen zur Verwendung des in-Schlüsselworts in diesen Kontexten und entsprechende Links finden Sie unter in.For more information on the use of the in keyword in these contexts, see in, which provides links to all those uses.

Variablen, die als in-Argumente übergeben wurden, müssen initialisiert werden, bevor sie in einen Methodenaufruf übergeben werden.Variables passed as in arguments must be initialized before being passed in a method call. Es kann jedoch sein, dass die aufgerufene Methode keinen Wert zuweist oder das Argument ändert.However, the called method may not assign a value or modify the argument.

Obwohl die Schlüsselwörter in, ref und out unterschiedliche Laufzeitverhalten hervorrufen, gelten sie zum Zeitpunkt der Kompilierung nicht als Teil der Methodensignatur.Although the in, ref, and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Aus diesem Grund können die Methoden nicht überladen werden, wenn der einzige Unterschied darin besteht, dass eine Methode ein ref- oder in-Argument übernimmt und die andere ein out-Argument.Therefore, methods cannot be overloaded if the only difference is that one method takes a ref or in argument and the other takes an out argument. Der folgende Code wird z. B. nicht kompiliert:The following code, for example, will not compile:

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on in, ref and out".
    public void SampleMethod(in int i) { }
    public void SampleMethod(ref int i) { }
}

Das Überladen bei vorhandenem in ist zulässig:Overloading based on the presence of in is allowed:

class InOverloads
{
    public void SampleMethod(in int i) { }
    public void SampleMethod(int i) { }
}

Regeln zur ÜberladungsauflösungOverload resolution rules

Die Regeln zur Auflösung von Methodenüberladungen bei der Übergabe von Argumenten als Wert und durch in lassen sich nachvollziehen, wenn die Motivation für in-Argumente bekannt ist.You can understand the overload resolution rules for methods with by value vs. in arguments by understanding the motivation for in arguments. Wenn Methoden mit in-Parametern definiert werden, kann unter Umständen eine Leistungsoptimierung erzielt werden.Defining methods using in parameters is a potential performance optimization. Einige struct-Typargumente beanspruchen viel Speicherplatz. Wenn dann in Schleifen mit vielen Durchläufen oder kritischen Codepfaden Methoden aufgerufen werden, ist der Aufwand zum Kopieren dieser Strukturen enorm.Some struct type arguments may be large in size, and when methods are called in tight loops or critical code paths, the cost of copying those structures is critical. Durch die Deklaration von in-Parametern in Methoden wird festgelegt, dass Argumente sicher als Verweis übergeben werden, da die aufgerufene Methode nicht den Zustand des Arguments ändert.Methods declare in parameters to specify that arguments may be passed by reference safely because the called method does not modify the state of that argument. Durch die Übergabe dieser Argumente als Verweis wird ein möglicherweise aufwendiges Kopieren vermieden.Passing those arguments by reference avoids the (potentially) expensive copy.

Die Angabe von in für Argumente an der Aufrufstelle ist üblicherweise optional.Specifying in for arguments at the call site is typically optional. Zwischen der Übergabe eines Arguments als Wert und der Übergabe als Verweis mithilfe des in-Modifizierers besteht kein semantischer Unterschied.There is no semantic difference between passing arguments by value and passing them by reference using the in modifier. Der in-Modifizierer an der Aufrufstelle ist optional, da nicht kenntlich gemacht werden muss, dass sich der Wert des Arguments ändern kann.The in modifier at the call site is optional because you don't need to indicate that the argument's value might be changed. Explizit geben Sie den in-Modifizierer an der Aufrufstelle an, wenn Sie sicherstellen möchten, dass das Argument als Verweis und nicht als Wert übergeben wird.You explicitly add the in modifier at the call site to ensure the argument is passed by reference, not by value. Die explizite Verwendung von in hat die folgenden beiden Auswirkungen:Explicitly using in has the following two effects:

Erstens wird der Compiler durch die Angabe von in an der Aufrufstelle dazu gezwungen, die Methode mit dem übereinstimmenden in-Parameter auszuwählen.First, specifying in at the call site forces the compiler to select a method defined with a matching in parameter. Wenn dies nicht der Fall ist und sich zwei Methoden nur durch die Angabe von in unterscheiden, wird die Methode überladen, für die Argumente als Wert übergeben werden.Otherwise, when two methods differ only in the presence of in, the by value overload is a better match.

Zweitens wird durch in festgelegt, dass ein Argument als Verweis übergeben wird.Second, specifying in declares your intent to pass an argument by reference. Das mit in verwendete Argument muss einen Speicherort darstellen, auf den direkt verwiesen werden kann.The argument used with in must represent a location that can be directly referred to. Es gelten die gleichen allgemeinen Regeln für out- und ref-Argumente: Sie können keine Konstanten, normale Eigenschaften oder andere Ausdrücke, die Werte erzeugen, verwenden.The same general rules for out and ref arguments apply: You cannot use constants, ordinary properties, or other expressions that produce values. Wird in an der Aufrufstelle weggelassen, wird der Compiler darüber informiert, dass die Erstellung einer temporären Variable und deren Übergabe als schreibgeschützter Verweis an die Methode zulässig ist.Otherwise, omitting in at the call site informs the compiler that you will allow it to create a temporary variable to pass by read-only reference to the method. Der Compiler erstellt in diesem Fall eine temporäre Variable, um mehrere Einschränkungen im Zusammenhang mit in-Argumenten zu umgehen:The compiler creates a temporary variable to overcome several restrictions with in arguments:

  • Eine temporäre Variable ermöglicht als Konstanten zur Kompilierzeit in-Parameter.A temporary variable allows compile-time constants as in parameters.
  • Eine temporäre Variable ermöglicht Eigenschaften oder andere Ausdrücke für in-Parameter.A temporary variable allows properties, or other expressions for in parameters.
  • Eine temporäre Variable ermöglicht Argumente, bei denen eine implizite Konvertierung des Argumenttyps in den Parametertyp vorgenommen wird.A temporary variable allows arguments where there is an implicit conversion from the argument type to the parameter type.

In den oben beschriebenen Fällen erstellt der Compiler eine temporäre Variable, die den Wert einer Konstante, einer Eigenschaft oder eines anderen Ausdrucks speichert.In all the preceding instances, the compiler creates a temporary variable that stores the value of the constant, property, or other expression.

Das folgende Codebeispiel veranschaulicht diese Regeln:The following code illustrates these rules:

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // OK, temporary variable created.
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // OK, temporary int created with the value 0
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // passed by readonly reference
Method(in i); // passed by readonly reference, explicitly using `in`

Gehen wir nun davon aus, dass eine weitere Methode verfügbar ist, für die Argumente als Wert übergeben werden:Now, suppose another method using by value arguments was available. Wie im folgenden Codebeispiel zu sehen ist, ändern sich die Ergebnisse:The results change as shown in the following code:

static void Method(int argument)
{
    // implementation removed
}

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // Calls overload passed by value
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // Calls overload passed by value.
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // Calls overload passed by value
Method(in i); // passed by readonly reference, explicitly using `in`

Nur beim letzten Methodenaufruf wird das Argument als Verweis übergeben.The only method call where the argument is passed by reference is the final one.

Hinweis

Im obigen Code wird aus Gründen der Einfachheit int als Argumenttyp verwendet.The preceding code uses int as the argument type for simplicity. Da auf den meisten modernen Computern int nicht größer ist als ein Verweis, ergibt sich kein Vorteil daraus, einen einzelnen int-Wert als schreibgeschützten Verweis zu übergeben.Because int is no larger than a reference in most modern machines, there is no benefit to passing a single int as a readonly reference.

Einschränkungen für in-ParameterLimitations on in parameters

Sie können keines der Schlüsselwörter in, ref und out für die folgenden Methodentypen verwenden:You can't use the in, ref, and out keywords for the following kinds of methods:

  • Asynchrone Methoden, die Sie mit dem async-Modifizierer definieren.Async methods, which you define by using the async modifier.
  • Iterator-Methoden, die eine yield return- oder yield break-Anweisung enthalten.Iterator methods, which include a yield return or yield break statement.

C#-ProgrammiersprachenspezifikationC# Language Specification

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation.For more information, see the C# Language Specification. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.The language specification is the definitive source for C# syntax and usage.

Siehe auchSee also