メソッド (C# プログラミング ガイド)Methods (C# Programming Guide)

メソッドは、一連のステートメントが含まれているコード ブロックです。A method is a code block that contains a series of statements. 必要なメソッド引数を指定してプログラムからメソッドを呼び出すと、メソッド内のステートメントが実行されます。A program causes the statements to be executed by calling the method and specifying any required method arguments. C# では、実行されるすべての命令がメソッドのコンテキストで実行されます。In C#, every executed instruction is performed in the context of a method. Main メソッドは、すべての C# アプリケーションのエントリ ポイントです。プログラムが開始されると、このメソッドが共通言語ランタイム (CLR) によって呼び出されます。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.

注意

このトピックでは、名前付きメソッドについて説明します。This topic discusses named methods. 匿名関数については、「匿名関数」を参照してください。For information about anonymous functions, see Anonymous Functions.

メソッド シグネチャMethod Signatures

メソッドは、 クラス または 構造体 で、アクセス レベル ( publicprivateなど)、オプションの修飾子 ( abstractsealedなど)、戻り値、メソッドの名前、およびメソッド パラメーターを指定して宣言します。Methods are declared in a class or struct by specifying the access level such as public or private, optional modifiers such as abstract or sealed, the return value, the name of the method, and any method parameters. これらのまとまりがメソッドのシグネチャとなります。These parts together are the signature of the method.

注意

メソッドのオーバーロードを可能にするために、メソッドの戻り値の型はメソッドのシグネチャには含まれません。A return type of a method is not part of the signature of the method for the purposes of method overloading. ただし、デリゲートとそれが指すメソッドの互換性を決定する場合には、メソッドのシグネチャの一部となります。However, it is part of the signature of the method when determining the compatibility between a delegate and the method that it points to.

メソッド パラメーターはかっこで囲み、各パラメーターをコンマで区切ります。Method parameters are enclosed in parentheses and are separated by commas. かっこ内を空にすると、メソッドでパラメーターが不要なことを意味します。Empty parentheses indicate that the method requires no parameters. このクラスには次の 4 つのメソッドが含まれています。This class contains four methods:

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

メソッド アクセスMethod Access

オブジェクトでメソッドを呼び出すのは、フィールドにアクセスするのと似ています。Calling a method on an object is like accessing a field. オブジェクト名の後に、ピリオド、メソッド名、かっこを追加します。After the object name, add a period, the name of the method, and parentheses. 引数はかっこの中に記述し、コンマで区切ります。Arguments are listed within the parentheses, and are separated by commas. Motorcycle クラスのメソッドの呼び出し例を次に示します。The methods of the Motorcycle class can therefore be called as in the following example:

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

メソッド パラメーターと引数Method Parameters vs. Arguments

メソッド定義には、必要なパラメーターの名前と型を指定します。The method definition specifies the names and types of any parameters that are required. 呼び出し元のコードからメソッドを呼び出すときに、各パラメーターに引数と呼ばれる具体的な値を指定します。When calling code calls the method, it provides concrete values called arguments for each parameter. 引数にはパラメーター型との互換性が必要ですが、呼び出し元のコードで引数名を使用する場合、引数名がメソッドで定義されるパラメーター名と同じである必要はありません。The arguments must be compatible with the parameter type but the argument name (if any) used in the calling code does not have to be the same as the parameter named defined in the method. 次に例を示します。For example:

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

参照渡しと値渡しPassing by Reference vs. Passing by Value

既定では、値型がメソッドに渡されるときは、オブジェクト自体ではなく、そのコピーが渡されます。By default, when a value type is passed to a method, a copy is passed instead of the object itself. したがって、引数に加えた変更は、呼び出し元のメソッドにある元のコピーには影響しません。Therefore, changes to the argument have no effect on the original copy in the calling method. ref キーワードを使用すると、値型を参照によって引き渡すことができます。You can pass a value-type by reference by using the ref keyword. 詳細については、「値型パラメーターの引き渡し」を参照してください。For more information, see Passing Value-Type Parameters. 組み込みの値型の一覧については、「値型の一覧表」を参照してください。For a list of built-in value types, see Value Types Table.

参照型のオブジェクトがメソッドに渡されると、オブジェクトへの参照が渡されます。When an object of a reference type is passed to a method, a reference to the object is passed. つまり、メソッドは、オブジェクト自体ではなく、オブジェクトの場所を示す引数を受け取ります。That is, the method receives not the object itself but an argument that indicates the location of the object. この参照を使用してオブジェクトのメンバーを変更した場合は、オブジェクトを値で渡しても、呼び出し元のメソッドの引数に変更が反映されます。If you change a member of the object by using this reference, the change is reflected in the argument in the calling method, even if you pass the object by value.

class キーワードを使用して参照型を作成する例を次に示します。You create a reference type by using the class keyword, as the following example shows.

public class SampleRefType
{
    public int value;
}

この型に基づくオブジェクトをメソッドに渡す場合は、オブジェクトへの参照が渡されます。Now, if you pass an object that is based on this type to a method, a reference to the object is passed. 次の例では、 SampleRefType 型のオブジェクトをメソッド ModifyObjectに渡します。The following example passes an object of type SampleRefType to method ModifyObject.

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

この例は、基本的に前の例と同様に、引数を値でメソッドに渡しています。The example does essentially the same thing as the previous example in that it passes an argument by value to a method. しかし、参照型を使用しているため、結果は異なります。But, because a reference type is used, the result is different. ModifyObject のパラメーター valueobjフィールドで行われた変更によって、 value メソッドの引数 rtTestRefType フィールドも変更されます。The modification that is made in ModifyObject to the value field of the parameter, obj, also changes the value field of the argument, rt, in the TestRefType method. TestRefType メソッドは出力として 33 を表示します。The TestRefType method displays 33 as the output.

参照型を参照渡しまたは値渡しで渡す方法の詳細については、「参照型パラメーターの引き渡し」と「参照型」を参照してください。For more information about how to pass reference types by reference and by value, see Passing Reference-Type Parameters and Reference Types.

戻り値Return Values

メソッドは、呼び出し元に値を返すことができます。Methods can return a value to the caller. 戻り値の型 (メソッド名の前に記述されている型) が voidでない場合、メソッドは、 return キーワードを使用して値を返すことができます。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. return キーワードに続いて戻り値の型に一致する値が記述されたステートメントは、その値をメソッドの呼び出し元に返します。A statement with the return keyword followed by a value that matches the return type will return that value to the method caller.

値を呼び出し元に返す方法には、値によって返す方法と、C# 7.0 以降の参照によって返す方法があります。The value can be returned to the caller by value or, starting with C# 7.0, by reference. 値が参照によって呼び出し元に返されるのは、ref キーワードがメソッド シグネチャで使用されていて、そのキーワードが各 return キーワードの後に続いている場合です。Values are returned to the caller by reference if the ref keyword is used in the method signature and it follows each return keyword. たとえば、次のメソッド シグネチャと return ステートメントは、メソッドが変数名 estDistance を参照によって呼び出し元に返すことを示しています。For example, the following method signature and return statement indicate that the method returns a variable names estDistance by reference to the caller.

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

また、 return キーワードは、メソッドの実行を中止します。The return keyword also stops the execution of the method. 戻り値の型が voidの場合、値を持たない return ステートメントは、メソッドの実行を中止するときに役立ちます。If the return type is void, a return statement without a value is still useful to stop the execution of the method. return キーワードを使用しない場合、メソッドは、コード ブロックの最後に到達したときに実行を中止します。Without the return keyword, the method will stop executing when it reaches the end of the code block. 戻り値の型が void 以外のメソッドで値を返すには、 return キーワードを使用する必要があります。Methods with a non-void return type are required to use the return keyword to return a value. たとえば、次の 2 つのメソッドは、 return キーワードを使用して整数を返します。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;
    }
}

メソッドから返された値を使用する場合、呼び出し元のメソッド内で同じ型の値を使用している場所では、メソッド呼び出し自体を値として使用できます。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. 戻り値は、変数に代入することもできます。You can also assign the return value to a variable. たとえば、次の 2 つのコードでは、同様の結果が得られます。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);

この場合、ローカル変数 resultを使用して値を格納する手順はオプションです。Using a local variable, in this case, result, to store a value is optional. このローカル変数によってコードの読みやすさが向上することがあります。また、引数の元の値をメソッドのスコープ全体で保持する場合に必要になることがあります。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.

メソッドから参照によって返された値を使用する場合、値を変更するには、ref ローカル変数を宣言する必要があります。To use a value returned by reference from a method, you must declare a ref local variable if you intend to modify its value. たとえば、Planet.GetEstimatedDistance メソッドが Double の値を参照によって返す場合は、次のようなコードを使用して、その値を ref ローカル変数として定義できます。For example, if the Planet.GetEstimatedDistance method returns a Double value by reference, you can define it as a ref local variable with code like the following:

ref int distance = plant 

呼び出し元の関数から、配列の内容を変更するメソッド M に配列が渡された場合、M から多次元配列を返す必要はありません。Returning a multi-dimensional array from a method, M, that modifies the array's contents is not necessary if the calling function passed the array into M. 値の適切なスタイルまたは機能フローのために M から結果の配列を返すことはできますが、必須ではありません。変更された配列を返す必要がないのは、C# ではすべての参照型が値で渡され、配列参照の値がその配列へのポインターになるためです。You may return the resulting array from M for good style or functional flow of values, but it is not necessary because C# passes all reference types by value, and the value of an array reference is the pointer to the array. メソッド M では、次の例に示すように、配列の内容に対する変更は、配列への参照を含むコードによって監視できます。In the method M, any changes to the array's contents are observable by any code that has a reference to the array, as shown in the following example.

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

詳細については、「 return」を参照してください。For more information, see return.

非同期メソッドAsync Methods

非同期機能を使用することによって、明示的なコールバックを使用せずに、または複数のメソッドやラムダ式にわたって手動でコードを分割することなく、非同期メソッドを呼び出すことができます。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.

メソッドに async 修飾子を付けると、そのメソッドで await 演算子を使用できます。If you mark a method with the async modifier, you can use the await operator in the method. コントロールが非同期メソッドの await 式に到達すると、コントロールは呼び出し元に戻り、待機中のタスクが完了するまでメソッドの進行状況は中断されます。When control reaches an await expression in the async method, control returns to the caller, and progress in the method is suspended until the awaited task completes. タスクが完了すると、メソッドで実行を再開できます。When the task is complete, execution can resume in the method.

注意

非同期メソッドは、まだ完了していない待機中の最初のオブジェクトに達するか、または非同期メソッドの最後に達すると、呼び出し元に戻ります。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.

非同期メソッドの戻り値の型としては、 Task<TResult>Task、または void を指定できます。An async method can have a return type of Task<TResult>, Task, or void. 戻り値の型 void は主として、void の戻り値の型が必要なイベント ハンドラーの定義に使用されます。The void return type is used primarily to define event handlers, where a void return type is required. void を返す非同期メソッドは待機できません。void を返すメソッドの呼び出し元は、このメソッドがスローする例外をキャッチできません。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.

次の例で、 DelayAsync は戻り値の型が Task<TResult>である非同期メソッドです。In the following example, DelayAsync is an async method that has a return type of Task<TResult>. DelayAsync には、整数を返す return ステートメントがあります。DelayAsync has a return statement that returns an integer. そのため、メソッド宣言 DelayAsync では、戻り値の型を Task<int>とする必要があります。Therefore the method declaration of DelayAsync must have a return type of Task<int>. 戻り値の型が Task<int>であるため、ステートメント await に示すように、 DoSomethingAsync 内の int result = await delayTask式を評価すると整数が生成されます。Because the return type is Task<int>, the evaluation of the await expression in DoSomethingAsync produces an integer as the following statement demonstrates: int result = await delayTask.

startButton_Click メソッドは、戻り値の型が void の非同期メソッドの例です。The startButton_Click method is an example of an async method that has a return type of void. DoSomethingAsync が非同期メソッドであるため、 DoSomethingAsync を呼び出すタスクは、ステートメント await DoSomethingAsync();に示すように待機する必要があります。Because DoSomethingAsync is an async method, the task for the call to DoSomethingAsync must be awaited, as the following statement shows: await DoSomethingAsync();. startButton_Click メソッドでは async 式が使用されているため、 await 修飾子を使用して定義する必要があります。The startButton_Click method must be defined with the async modifier because the method has an await expression.

// 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

非同期メソッドで ref パラメーターまたは out パラメーターを宣言することはできませんが、これらのパラメーターを持つメソッドを呼び出すことはできます。An async method can't declare any ref or out parameters, but it can call methods that have such parameters.

非同期メソッドの詳細については、「Async および Await を使用した非同期プログラミング」、「非同期プログラムにおける制御フロー」、「非同期の戻り値の型」を参照してください。For more information about async methods, see Asynchronous Programming with async and await, Control Flow in Async Programs, and Async Return Types.

式の本文の定義Expression Body Definitions

メソッドの定義としては、式の結果を即座に返すか、またはメソッドの本文として 1 つのステートメントを含むものが一般的です。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. =>を使用してこのようなメソッドを定義するための構文ショートカットがあります。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);  

メソッドが void を返すか、非同期メソッドである場合は、メソッドの本文を (ラムダの場合と同様に) ステートメント式にする必要があります。If the method returns void or is an async method, then the body of the method must be a statement expression (same as with lambdas). プロパティとインデクサーは読み取り専用にする必要があるため、 get アクセサー キーワードは使用しないでください。For properties and indexers, they must be read only, and you don't use the get accessor keyword.

IteratorsIterators

反復子は、リストや配列など、コレクションに対するカスタム イテレーションを実行します。An iterator performs a custom iteration over a collection, such as a list or an array. 反復子は、 yield return ステートメントを使用して、各要素を 1 回に1 つ返します。An iterator uses the yield return statement to return each element one at a time. yield return ステートメントに達すると、コードの現在の場所が記憶されます。When a yield return statement is reached, the current location in code is remembered. 反復子が次回呼び出されたとき、この場所から実行が再開されます。Execution is restarted from that location when the iterator is called the next time.

foreach ステートメントを使用して、クライアント コードから反復子を呼び出します。You call an iterator from client code by using a foreach statement.

反復子の戻り値の型には、 IEnumerableIEnumerable<T>IEnumerator、または IEnumerator<T>を指定できます。The return type of an iterator can be IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>.

詳細については、「 反復子」を参照してください。For more information, see Iterators.

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