メソッドMethods

メソッドは、一連のステートメントが含まれているコード ブロックです。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.

このトピックは、次のセクションで構成されています。This topic contains the following sections:

メソッド シグネチャMethod signatures

メソッドは次の項目を指定することで class または struct で宣言されます。Methods are declared in a class or struct by specifying:

  • publicprivate など、任意のアクセス レベル。An optional access level, such as public or private. 既定値は、private です。The default is private.
  • abstractsealed など、任意の修飾子。Optional modifiers such as abstract or sealed.
  • メソッドに何も与えられていない場合、戻り値または voidThe return value, or void if the method has none.
  • メソッド名。The method name.
  • メソッド パラメーター。Any method parameters. メソッド パラメーターはかっこで囲み、各パラメーターをコンマで区切ります。Method parameters are enclosed in parentheses and are separated by commas. かっこ内を空にすると、メソッドでパラメーターが不要なことを意味します。Empty parentheses indicate that the method requires no parameters.

これらのまとまりがメソッド シグネチャとなります。These parts together form the method signature.

注意

メソッドのオーバーロードを可能にするために、メソッドの戻り値の型はメソッドのシグネチャには含まれません。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.

次の例では、5 つのメソッドを含む Motorcycle という名前のクラスを定義します。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(); 
}

Motorcycle クラスにオーバーロードされたクラス Drive が含まれていることに注意してください。Note that the Motorcycle class includes an overloaded method, Drive. 2 つのメソッドの名前が同じであり、パラメーターの種類で識別する必要があります。Two methods have the same name, but must be differentiated by their parameter types.

メソッドの呼び出しMethod invocation

メソッドはインスタンスまたは静的になります。Methods can be either instance or static. インスタンス メソッドを呼び出すには、オブジェクトをインスタンス化し、そのオブジェクトでメソッドを呼び出す必要があります。インスタンス メソッドはこのインスタンスとそのデータを操作します。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. メソッドが属する型の名前を参照して静的メソッドを呼び出します。静的メソッドはインスタンス データを操作しません。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. オブジェクト インスタンス経由で静的メソッドを呼び出そうとすると、コンパイラ エラーが発生します。Attempting to call a static method through an object instance generates a compiler error.

メソッドを呼び出すことは、フィールドにアクセスするのと似ています。Calling a method is like accessing a field. オブジェクトの名前 (インスタンス メソッドを呼び出す場合) または型の名前 (static メソッドを呼び出す場合) の後ろに、期間、メソッドの名前、かっこを追加します。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. 引数はかっこの中に記述し、コンマで区切ります。Arguments are listed within the parentheses, and are separated by commas.

メソッド定義には、必要なパラメーターの名前と型を指定します。The method definition specifies the names and types of any parameters that are required. 呼び出し元からメソッドを呼び出すとき、各パラメーターに引数と呼ばれる具体的な値を指定します。When a caller invokes 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 one is used in the calling code, does not have to be the same as the parameter named defined in the method. 次の例では、Square メソッドに型が inti という名前のパラメーターが 1 つ含まれています。In the following example, the Square method includes a single parameter of type int named i. 最初のメソッド呼び出しでは、型が intnum という名前の変数が Square メソッドに渡されます。2 つ目のメソッド呼び出しでは数値定数が、3 つ目のメソッド呼び出しでは式が渡されます。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;
   }
}

メソッド呼び出しの最も一般的な形式では、位置引数が使用されます。これはメソッド パラメーターと同じ順序で引数を指定するものです。The most common form of method invocation used positional arguments; it supplies arguments in the same order as method parameters. そのため、Motorcycle クラスのメソッドは次の例のように呼び出されます。The methods of the Motorcycle class can therefore be called as in the following example. たとえば、Drive メソッドの呼び出しには 2 つの引数が含まれます。この 2 つの引数は、メソッドの構文の 2 つのパラメーターに対応しています。The call to the Drive method, for example, includes two arguments that correspond to the two parameters in the method's syntax. 1 つ目は miles パラメーターの値になります。2 つ目は speed パラメーターの値になります。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);            
   }
}

メソッドを呼び出すとき、位置引数の代わりに名前付き引数を使用することもできます。You can also used named arguments instead of positional arguments when invoking a method. 名前付き引数を使用するとき、パラメーター名に続けてコロン (":") と引数を指定します。When using named arguments, you specify the parameter name followed by a colon (":") and the argument. 必要なすべての引数が存在する限り、メソッドの引数の順序は問われません。Arguments to the method can appear in any order, as long as all required arguments are present. 次の例では、名前付き引数を使用して TestMotorcycle.Drive メソッドを呼び出しています。The following example uses named arguments to invoke the TestMotorcycle.Drive method. この例では、メソッドのパラメーター リストとは反対の順序で名前付き引数が渡されています。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

位置引数と名前付き引数の両方を利用してメソッドを呼び出すことができます。You can invoke a method using both positional arguments and named arguments. ただし、名前付き引数の後に位置指定引数を使用することはできません。However, a positional argument cannot follow a named argument. 次の例では、前の例にあった TestMotorcycle.Drive メソッドを呼び出していますが、位置引数が 1 つ、名前付き引数が 1 つ使用されています。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);

##継承されたメソッドとオーバーライドされたメソッドInherited and overridden methods ##

型に明示的に定義されるメンバーに加え、型は、その基底クラスに定義されているメンバーを継承します。In addition to the members that are explicitly defined in a type, a type inherits members defined in its base classes. マネージ型システムのすべての型から直接または間接的を継承するので、Objectなど、クラス、すべての型の継承、メンバー Equals(Object)GetType()、および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(). 次の例では、Person クラスを定義し、2 つの Person オブジェクトをインスタンス化し、Person.Equals メソッドを呼び出して 2 つのオブジェクトが等しいかどうかを判断します。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. ただし、Equals メソッドは Person クラスに定義されていません。Object から継承されたものです。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

型は継承されたメンバーをオーバーライドできます。override キーワードを使用し、オーバーライドされたメソッドを実装します。Types can override inherited members by using the override keyword and providing an implementation for the overridden method. メソッドのシグネチャは、オーバーライドされたメソッドと同じである必要があります。The method signature must be the same as that of the overridden method. 次の例は、1 つ前のようにオーバーライドする点を除いて、Equals(Object)メソッドです。The following example is like the previous one, except that it overrides the Equals(Object) method. (この 2 つのメソッドは一貫性のある結果を提供するため、GetHashCode() メソッドもオーバーライドされます。)(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

パラメーターを渡すPassing parameters

C# の型は、値型参照型のどちらかに区別されます。Types in C# are either value types or reference types. 組み込みの値型の一覧については、「型と変数」を参照してください。For a list of built-in value types, see Types and variables. 既定では、値型と参照型の両方が値によりメソッドに渡されます。By default, both value types and reference types are passed to a method by value.

パラメーターを値で渡すPassing parameters by value

値型が値でメソッドに渡されるとき、オブジェクト自体の代わりにオブジェクトのコピーがメソッドに渡されます。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. そのため、呼び出されたメソッドでオブジェクトに加えた変更は、コントロールが呼び出し元に戻ったとき、元のオブジェクトで反映されません。Therefore, changes to the object in the called method have no effect on the original object when control returns to the caller.

次の例では、値型を値でメソッドに渡します。呼び出されたメソッドが値型の値を変更しようとします。The following example passes a value type to a method by value, and the called method attempts to change the value type's value. int (値型) の変数を定義し、その値を 20 に初期化し、ModifyValue という名前のメソッドに値を渡します。このメソッドは変数の値を 30 に変更します。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. しかしながら、メソッドが戻ると、変数の値は元のままです。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

参照型のオブジェクトが値でメソッドに渡されると、オブジェクトへの参照が値で渡されます。When an object of a reference type is passed to a method by value, a reference to the object is passed by value. つまり、メソッドは、オブジェクト自体ではなく、オブジェクトの場所を示す引数を受け取ります。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 object when control returns to the calling method. ただし、メソッドに渡されるオブジェクトを置換しても、コントロールが呼び出し元に戻ったとき、元のオブジェクトで反映されません。However, replacing the object passed to the method has no effect on the original object when control returns to the caller.

次の例では、SampleRefType という名前のクラス (参照型) を定義します。The following example defines a class (which is a reference type) named SampleRefType. SampleRefType オブジェクトをインスタンス化し、その value フィールドに 44 を割り当て、ModifyObject メソッドにオブジェクトを渡します。It instantiates a SampleRefType object, assigns 44 to its value field, and passes the object to the ModifyObject method. この例は、基本的に前の例と同様に、引数を値でメソッドに渡しています。This example does essentially the same thing as the previous example -- it passes an argument by value to a method. ただし、参照型を使用しているため、結果は異なります。But because a reference type is used, the result is different. ModifyObjectobj.value フィールドを変更したことで、Main メソッドの引数 rtvalue フィールドも 33 に変更されます。例の出力で確認できます。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;
    }
}

パラメーターの参照渡しPassing parameters by reference

メソッドの引数の値を変更し、コントロールが呼び出し元に戻ったときにその変更を反映させるには、参照でパラメーターを渡します。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. パラメーターを参照で渡すには、キーワードの ref または out を使用します。To pass a parameter by reference, you use the ref or out keyword.

次の例は前の例とよく似ていますが、値が参照で ModifyValue メソッドに渡される点が異なります。The following example is identical to the previous one, except the value is passed by reference to the ModifyValue method. パラメーターの値が ModifyValue メソッドで変更されると、コントロールが呼び出し元に戻ったとき、地の変更が反映されます。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

参照型パラメーターを利用する典型的なパターンが変数の値の入れ替えです。A common pattern that uses by ref parameters involves swapping the values of variables. 参照でメソッドに 2 つの変数を渡すと、メソッドがその中身を入れ替えます。You pass two variables to a method by reference, and the method swaps their contents. 次の例では、整数値が入れ替えられます。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

参照型パラメーターを渡すことで、個々の要素またはフィールドの値ではなく、参照自体の値を変更できます。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.

パラメーター配列Parameter arrays

メソッドに厳密な数の引数を指定する要件が限定的になることがあります。Sometimes, the requirement that you specify the exact number of arguments to your method is restrictive. params キーワードを利用し、パラメーターがパラメーター配列であることを示すことで、可変数の引数でメソッドを呼び出すことができます。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. params キーワードでタグが付けられたパラメーターは配列型にする必要があり、メソッドのパラメーター リストの最後のパラメーターにする必要があります。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.

呼び出し元は、次の 3 つの方法のいずれかでメソッドを呼び出すことができます。A caller can then invoke the method in either of three ways:

  • 必要な数の要素を含む、適切な型の配列を渡す。By passing an array of the appropriate type that contains the desired number of elements.
  • 適切な型の引数をコンマで区切った一覧をメソッドに渡す。By passing a comma-separated list of individual arguments of the appropriate type to the method.
  • パラメーター配列に引数を指定しない。By not providing an argument to the parameter array.

次の例では、DoStringOperation という名前のメソッドを定義します。このメソッドは、その最初のパラメーターである StringOperation 列挙メンバーにより指定された文字列操作を実行します。The following example defines a method named DoStringOperation that performs the string operation specified by its first parameter, a StringOperation enumeration member. 操作の実行対象である文字列はパラメーター配列により設定されます。The strings upon which it is to perform the operation are defined by a parameter array. Main メソッドには、メソッド呼び出しの 3 つ全部の方法が入っています。The Main method illustrates all three ways of invoking the method. パラメーター配列に引数が指定されず、その値が null になるケースを処理するには、params キーワードでタグが付けられたメソッドを用意する必要があります。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

省略可能なパラメーターと引数Optional parameters and arguments

メソッド定義では、そのパラメーターが必須であるか、任意であるかを指定できます。A method definition can specify that its parameters are required or that they are optional. 既定では、パラメーターは必須です。By default, parameters are required. 省略可能なパラメーターを指定するには、メソッド定義にパラメーターの既定値を追加します。Optional parameters are specified by including the parameter's default value in the method definition. メソッドが呼び出されるとき、省略可能なパラメーターに引数が指定されていなければ、既定値が代わりに使用されます。When the method is called, if no argument is supplied for an optional parameter, the default value is used instead.

パラメーターの既定値は、次の種類の式のいずれかで割り当てる必要があります。The parameter's default value must be assigned by one of the following kinds of expressions:

  • リテラル文字列や数値など、定数。A constant, such as a literal string or number.
  • ValType が値型となる、new ValType 形式の式。An expression of the form new ValType, where ValType is a value type. 型の実際のメンバーではない、値型の暗黙の既定コンストラクターが呼び出されることに注意してください。Note that this invokes the value type's implicit default constructor, which is not an actual member of the type.
  • ValType が値型となる、default(ValType) 形式の式。An expression of the form default(ValType), where ValType is a value type.

メソッドに必須のパラメーターと省略可能なパラメーターの両方が含まれる場合、省略可能なパラメーターはパラメーター リストの終わりに定義されます (すべての必須パラメーターの後に)。If a method includes both required and optional parameters, optional parameters are defined at the end of the parameter list, after all required parameters.

次の例では、ExampleMethod メソッドを定義しています。必須のパラメーターが 1 つ、省略可能なパラメーターが 2 つあります。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);
   }
}

省略可能なパラメーターを複数持つメソッドが位置引数で呼び出された場合、呼び出し元は、引数が指定される最初のパラメーターから最後のパラメーターまで、すべての省略可能なパラメーターに引数を指定する必要があります。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. たとえば、ExampleMethod メソッドの場合、呼び出し元が description パラメーターの引数を指定した場合、optionalInt パラメーターの引数も指定する必要があります。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"); は有効なメソッド呼び出しです。opt.ExampleMethod(2, , "Addition of 2 and 0); は、"引数がありません" というコンパイラ エラーを発生させます。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.

メソッドが名前付き引数または位置引数と名前付き引数の組み合わせで呼び出される場合、呼び出し元は、メソッド呼び出しの最後の位置引数の後に続く引数を省略できます。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.

次の例では、ExampleMethod メソッドが 3 回呼び出されます。The following example calls the ExampleMethod method three times. 最初の 2 つのメソッド呼び出しでは、位置引数が使用されます。The first two method calls use positional arguments. 最初の呼び出しではいずれの省略可能なパラメーターも省略され、2 つ目の呼び出しでは最後の引数が省略されます。The first omits both optional arguments, while the second omits the last argument. 3 つ目のメソッドは必須パラメーターの位置引数を指定しますが、名前付き引数を利用して description パラメーターに値を指定します。optionalInt パラメーターは省略します。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

省略可能なパラメーターの使用は、オーバーロードの解決に影響を与えます。次のように、特定のオーバーロードをメソッド呼び出しで呼び出すかどうかを C# コンパイラが決定する方法に影響を与えます。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:

  • メソッド、インデクサー、コンストラクターのパラメーターのそれぞれが任意であるか、名前か位置により、呼び出しステートメントの 1 つの引数に対応するとき、その引数がパラメーターの型に変換できる場合、メソッド、インデクサー、コンストラクターが実行の候補になります。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.
  • 複数の候補が見つかった場合、明示的に指定される引数には、優先変換に関するオーバーロード解決の規則が適用されます。If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. 任意のパラメーターの省略された引数は無視されます。Omitted arguments for optional parameters are ignored.
  • 2 つの候補が等しく良好であると判断された場合、呼び出しで引数が省略された任意のパラメーターのない候補が優先されます。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. これはパラメーターの少ない候補に関するオーバーロード解決の一般優先設定の結果です。This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

戻り値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 variable, constant, or expression that matches the return type will return that value to the method caller. 戻り値の型が void 以外のメソッドで値を返すには、 return キーワードを使用する必要があります。Methods with a non-void return type are required to use the return keyword to return a value. また、 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.

たとえば、次の 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.

メソッドで複数の値を返すと便利な場合があります。Sometimes, you want your method to return more than a single value. C# 7.0 以降では、タプル型タプル リテラルを使用してこれを簡単に実行できます。Starting with C# 7.0, you can do this easily by using tuple types and tuple literals. タプル型は、タプルの要素のデータ型を決定します。The tuple type defines the data types of the tuple's elements. タプル リテラルは、返されたタプルの実際の値を提供します。Tuple literals provide the actual values of the returned tuple. 次の例では、(string, string, string, int)によって返される組の型を定義、GetPersonalInfoメソッドです。In the following example, (string, string, string, int) defines the tuple type that is returned by the GetPersonalInfo method. (per.FirstName, per.MiddleName, per.LastName, per.Age) はタプル リテラルです。このメソッドは、PersonInfo オブジェクトの名、ミドルネーム、姓、年齢を返します。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;
}

呼び出し元はそれから、次のようなコードで返されたタプルを利用します。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}");

名前は、タプル型の定義のタプル要素に割り当てることもできます。Names can also be assigned to the tuple elements in the tuple type definition. 次の例は、名前付き要素を使用する GetPersonalInfo メソッドの別バージョンです。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;
}

この例の GetPersonInfo メソッドの呼び出しは次のように変更できます。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}");

メソッドに引数として配列が渡されるとき、そのメソッドが個々の要素の値を変更する場合、メソッドが配列を返す必要はありません。ただし、見やすいから、値の流れが機能的になるからといった理由で配列を返してもかまいません。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. 配列を返す必要がないのは、C# ではすべての参照型が値で渡され、配列参照の値がその配列のポインターになるためです。This is because C# passes all reference types by value, and the value of an array reference is the pointer to the array. 次の例では、DoubleValues メソッドで行われた values 配列の内容の変更を、配列の参照があるあらゆるコードで観察できます。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

拡張メソッドExtension methods

通常、既存の型にメソッドを追加する方法が 2 つあります。Ordinarily, there are two ways to add a method to an existing type:

  • その型のソース コードを変更する。Modify the source code for that type. もちろん、型のソース コードを所有していない場合、これはできません。You cannot do this, of course, if you do not own the type's source code. また、メソッドをサポートするプライベース データ フィールドも追加した場合、これは互換性に影響する変更になります。And this becomes a breaking change if you also add any private data fields to support the method.
  • 派生クラスで新しいメソッドを定義する。Define the new method in a derived class. 構造体や列挙型など、その他の型の継承を利用し、メソッドをこの方法で追加することはできません。A method cannot be added in this way using inheritance for other types, such as structures and enumerations. シール クラスにメソッドを "追加する" こともできません。Nor can it be used to "add" a method to a sealed class.

拡張メソッドでは、型自体を変更せずに、あるいは継承された型に新しいメソッドを実装せずに、既存の型にメソッドを "追加" できます。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. また、拡張メソッドは、それが拡張する型と同じアセンブリに置く必要がありません。The extension method also does not have to reside in the same assembly as the type it extends. 型の定義済みメンバーのように拡張メソッドを呼び出します。You call an extension method as if it were a defined member of a type.

詳細については、「拡張メソッド」を参照してください。For more information, see Extension Methods.

非同期メソッド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 式に到達すると、待機中のタスクが完了していない場合、コントロールが呼び出し元に戻ります。await キーワードが与えられたメソッドの進行は、待機中のタスクが完了するまで中断されます。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. タスクが完了すると、メソッドで実行を再開できます。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. C# 7 がリリースされるとこの制約が緩和され、非同期メソッドでタスクと同種のあらゆる型を返すことができるようになります。C# 7, when it is released, will ease this restriction to allow an async method to return any task-like type.

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

非同期メソッドで 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-bodied members

メソッドの定義としては、式の結果を即座に返すか、またはメソッドの本文として 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, 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 do not use the get accessor keyword.

反復子Iterators

反復子は、リストや配列など、コレクションに対するカスタム イテレーションを実行します。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 is remembered so that the caller can request the next element in the sequence.

反復子の戻り値の型には、 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.

関連項目See also

アクセス修飾子 Access Modifiers
静的クラスと静的クラス メンバー Static Classes and Static Class Members
継承 Inheritance
抽象クラスとシール クラス、およびクラス メンバー Abstract and Sealed Classes and Class Members
params params
out out
ref ref
パラメーターの引き渡しPassing Parameters