in パラメーター修飾子 (C# リファレンス)in parameter modifier (C# Reference)

in キーワードによって、参照により引数が渡されます。The in keyword causes arguments to be passed by reference. 仮パラメーターを引数 (変数にする必要があります) の別名にします。It makes the formal parameter an alias for the argument, which must be a variable. つまり、パラメーターに対するすべての操作は引数に対して行われます。In other words, any operation on the parameter is made on the argument. これは、ref または out キーワードと似ています。ただし、呼び出されたメソッドで in 引数を変更することはできません。It is like the ref or out keywords, except that in arguments cannot be modified by the called method. ref 引数には変更が許される一方で、out 引数の場合、呼び出されたメソッドによって変更される必要があります。そのような変更は、呼び出し元のコンテキストで観察できます。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;
}

前の例は、通常、in 修飾子が呼び出しサイトでは不要であることを示しています。The preceding example demonstrates that the in modifier is usually unnecessary at the call site. これはメソッド宣言でのみ必要です。It is only required in the method declaration.

注意

foreach ステートメントの一部、または LINQ クエリの join 句の一部として、型パラメーターが反変であることを示すために in キーワードをジェネリック型パラメーターで使用することもできます。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. これらのコンテキストでの in キーワードの使用の詳細については、これらすべての使用に関するリンクを提供する「in」を参照してください。For more information on the use of the in keyword in these contexts, see in, which provides links to all those uses.

in 引数として渡される変数は、メソッド呼び出しで渡される前に初期化する必要があります。Variables passed as in arguments must be initialized before being passed in a method call. ただし、呼び出されたメソッドでは値の割り当てや、引数の変更を行うことはできません。However, the called method may not assign a value or modify the argument.

in パラメーター修飾子は C# 7.2 以降で使用可能です。The in parameter modifier is available in C# 7.2 and later. 以前のバージョンでは、コンパイラ エラー CS8107 ("Feature 'readonly references' is not available in C# 7.0.Previous versions generate compiler error CS8107 ("Feature 'readonly references' is not available in C# 7.0. Please use language version 7.2 or greater." ('読み取り専用参照' 機能は C# 7.0 では使用できません。7.2 以上の言語バージョンを使用してください)) が生成されました。コンパイラ言語のバージョンを構成するには、「C# 言語のバージョンの選択」をご覧ください。Please use language version 7.2 or greater.") To configure the compiler language version, see Select the C# language version.

inref、および out キーワードは、オーバーロード解決のためのメソッド シグネチャの一部とは見なされません。The in, ref, and out keywords are not considered part of the method signature for the purpose of overload resolution. したがって、唯一の違いが、1 つのメソッドは ref または in 引数を受け取り、もう一方のメソッドは out 引数を受け取ることである場合、メソッドはオーバーロードできません。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. たとえば、次のコードはコンパイルされません。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) { }
}

in の有無に基づくオーバーロードが可能です。Overloading based on the presence of in is allowed:

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

オーバーロードの解決ルールOverload resolution rules

in 引数の意図を理解して、値と in 引数の比較によって、メソッドに対するオーバーロードの解決ルールを理解できます。You can understand the overload resolution rules for methods with by value vs. in arguments by understanding the motivation for in arguments. in パラメーターを使用してメソッドを定義すると、パフォーマンスを最適化できる可能性があります。Defining methods using in parameters is a potential performance optimization. 一部の struct 型引数は、サイズが大きくなる可能性があり、メソッドが短いループまたは重要なコード パスで呼び出される場合、その構造のコピーのコストが重要になります。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. 呼び出されたメソッドは引数の状態を変更しないため、メソッドで in パラメーターを宣言して、参照で安全に渡すことができる引数を指定します。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. 参照によりこれらの引数を渡して、(可能性がある) 高額なコピーを回避します。Passing those arguments by reference avoids the (potentially) expensive copy.

呼び出しサイトで引数に in を指定することは、通常は省略可能です。Specifying in for arguments at the call site is typically optional. 値で引数を渡す場合と in 修飾子を使用して参照で渡す場合の間に、セマンティックの相違点はありません。There is no semantic difference between passing arguments by value and passing them by reference using the in modifier. 引数の値が変更される可能性があることを示す必要はないため、呼び出しサイトの in 修飾子は省略可能です。The in modifier at the call site is optional because you don't need to indicate that the argument's value might be changed. 呼び出しサイトで in 修飾子を明示的に追加して、引数が値ではなく、参照で渡されるようにします。You explicitly add the in modifier at the call site to ensure the argument is passed by reference, not by value. 明示的に in を使用すると、次の 2 つの効果があります。Explicitly using in has the following two effects:

1 つ目は、呼び出しサイトで in を指定すると、一致する in パラメーターで定義されたメソッドがコンパイラで強制的に選択されます。First, specifying in at the call site forces the compiler to select a method defined with a matching in parameter. それ以外の場合は、2 つのメソッドで in の有無のみが異なるときは、値によるオーバーロードの方が適しています。Otherwise, when two methods differ only in the presence of in, the by value overload is a better match.

2 つ目は、in を指定して、参照で引数を渡す意図を宣言します。Second, specifying in declares your intent to pass an argument by reference. in で使用される引数では、直接参照できる場所を表す必要があります。The argument used with in must represent a location that can be directly referred to. out および ref 引数と同じ一般ルールが適用されます。定数、通常のプロパティ、または値を生成するその他の式を使用することはできません。The same general rules for out and ref arguments apply: You cannot use constants, ordinary properties, or other expressions that produce values. それ以外の場合は、呼び出しサイトで in を省略すると、メソッドに読み取り専用の参照で渡すために、一時変数の作成を許可することが、コンパイラに通知されます。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. コンパイラでは、一時変数を作成して、in 引数でのいくつかの制限に対処します。The compiler creates a temporary variable to overcome several restrictions with in arguments:

  • 一時変数では、in パラメーターとしてコンパイル時の定数を許可します。A temporary variable allows compile-time constants as in parameters.
  • 一時変数では、プロパティ、または in パラメーターのその他の式を許可します。A temporary variable allows properties, or other expressions for in parameters.
  • 一時変数では、引数型からパラメーターの型への暗黙の変換がある引数を許可します。A temporary variable allows arguments where there is an implicit conversion from the argument type to the parameter type.

先のすべてのインスタンスで、コンパイラは定数、プロパティ、またはその他の式の値を格納する一時変数を作成します。In all the preceding instances, the compiler creates a temporary variable that stores the value of the constant, property, or other expression.

これらのルールが発生するコード例を次に示します。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`

ここでは、値の引数で使用する別のメソッドが使用できたと想定します。Now, suppose another method using by value arguments was available. 次のコードに示すように、結果が変更されます。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`

引数が参照で渡されるメソッドの呼び出しは、最後のメソッドのみです。The only method call where the argument is passed by reference is the final one.

注意

先のコードでは、わかりやすくするために int を引数型として使用します。The preceding code uses int as the argument type for simplicity. int は最新のマシンの参照より大きくなることはないため、読み取り専用の参照として単一の int を渡すメリットはありません。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.

in パラメーターの制限Limitations on in parameters

次の種類のメソッドには、inrefout キーワードを使用することはできません。You can't use the in, ref, and out keywords for the following kinds of methods:

  • async 修飾子を使用して定義した Async メソッド。Async methods, which you define by using the async modifier.
  • yield return または yield break ステートメントを含む Iterator メソッド。Iterator methods, which include a yield return or yield break statement.

C# 言語仕様C# Language Specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

関連項目See also