C# 方法(Methods)
メソッド(Method)は、関連する一連のステートメントをまとめて、特定のタスクを実行するためのコードブロックです。これはC#での実装です。代码复用と逻辑封装の中核メカニズム。すべての C# プログラムには少なくとも1つのMainメソッドをプログラムのエントリポイントとして使用します。
メソッドの使用には2つの手順が必要です:定义方法と调用方法。
1. メソッドを定義する
C# でメソッドを定義する基本構文は次のとおりです。
<アクセス修飾子> <戻り値の型> <メソッド名>(<パラメータリスト>)
{
メソッド本体
}
メソッドは次の要素で構成されます:
- 访问修饰符(アクセス修飾子):メソッドの可視性を制御します。例えば、
public、private、protected、internal。 - 返回类型(Return Type):メソッドの戻り値のデータ型。メソッドが値を返さない場合は、使用します。
void。 - 方法名(メソッド名):メソッドの一意の識別子であり、PascalCase 命名規則を使用します(例:
FindMax、GetUserName)。 - 参数列表(Parameter List):メソッドが受け取る入力。丸括弧で囲みます。パラメータは省略可能で、メソッドはパラメータなしにできます。
- 方法体(Method Body):機能を実装するコードを含み、波括弧で
{}包围。
次の図は、メソッドの完全な構造を示しています。
1.1 最初のメソッドの例
以下では~を定義していますFindMaxメソッドは、2つの整数を受け取り、そのうち大きい方を返します。
实例
namespace MethodDemo
{
class NumberHelper
{
// メソッドを定義: 2 つの int を受け取り、大きい方を返す
public int FindMax(int num1, int num2)
{
if (num1 > num2)
return num1;
else
return num2;
}
static void Main(string[] args)
{
// オブジェクトを作成してメソッドを呼び出します
NumberHelper helper = new NumberHelper();
int result = helper.FindMax(100, 200);
Console.WriteLine($最大値は:{result}); // 最大値は:200
}
}
}
メソッドの呼び出しフロー:
跨类调用:メソッドが次のように宣言されていれば
public、他のクラスからインスタンスを作成して呼び出すことができます。これはオブジェクト指向プログラミングにおけるコード再利用の基礎です。
2. パラメータの渡し方
C# はメソッドにパラメータを渡す3つの方法を提供します。それらの核心的な違いは次のとおりです。メモリを共有するかどうか:
| 方式 | 关键字 | 動作 | 典型场景 |
|---|---|---|---|
| 按值传递 | (无) | パラメータの値をコピーし、メソッド内で変更しても元の変数には影響しません。 | ほとんどのメソッド呼び出し(デフォルト) |
| 按引用传递 | ref |
変数の参照を渡します。メソッド内での変更は元の変数を変更します。 | 外部変数の変更が必要な場合(値の交換など) |
| 输出参数 | out |
ref に似ていますが、メソッド内で代入する必要があり、呼び出し前に初期化する必要はありません。 | メソッドが複数の値を返す必要がある |
2.1 値渡し(デフォルト)
値渡しがデフォルトです。実引数の値は复制仮引数に渡されます。メソッド内での仮引数の変更は元の変数に影響しません。
实例
namespace ParameterDemo
{
class Program
{
// 値渡し:x と y は a、b のコピー
public void Swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
Console.WriteLine($" 方法内:x={x}, y={y}"); // 交换成功
}
static void Main(string[] args)
{
var p = new Program();
int a = 100, b = 200;
Console.WriteLine($"调用前:a={a}, b={b}");
p.Swap(a, b);
Console.WriteLine($"调用后:a={a}, b={b}"); // a、b 没有变化!
}
}
}
调用前:a=100, b=200 方法内:x=200, y=100 调用后:a=100, b=200
2.2 参照渡し(ref)
使用refキーワードを使用して変数を渡します引用(メモリ上のアドレス)であり、メソッド内での仮引数の変更は元の変数に直接影響します。呼び出し時にも必ずref:
实例
namespace ParameterDemo
{
class Program
{
// 参照渡し:x と y は a、b のメモリを直接参照します
public void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
static void Main(string[] args)
{
var p = new Program();
int a = 100, b = 200;
Console.WriteLine($"调用前:a={a}, b={b}");
p.Swap(ref a, ref b); // 调用时也必须加 ref
Console.WriteLine($"调用后:a={a}, b={b}"); // 交换成功!
}
}
}
调用前:a=100, b=200 调用后:a=200, b=100
refとoutの違い:
ref変数は渡す前に初期化済みである必要があります事前に初期化されている必要がある;out必要ではありませんが、メソッド内部ではoutパラメータに値を代入する必要があるその後で使用できます。
2.3 出力パラメータ(out)
outパラメータによってメソッドは~できます返回多个值。とref異なる点は、呼び出し前に変数を初期化する必要はありませんが、メソッド内部で代入する必要があることです。
实例
namespace ParameterDemo
{
class Program
{
// out 参数:方法负责赋值
public void GetValues(out int x, out int y)
{
Console.Write("请输入第一个值:");
x = Convert.ToInt32(Console.ReadLine());
Console.Write("请输入第二个值:");
y = Convert.ToInt32(Console.ReadLine());
// 注意:メソッド終了前にすべての out パラメータに値を代入しなければなりません。そうしないとコンパイルエラーになります。
}
// 实用示例:TryParse 模式
public bool TryDivide(int a, int b, out double result)
{
if (b == 0)
{
result = 0;
return false; // 除数がゼロ
}
result = (double)a / b;
return true;
}
static void Main(string[] args)
{
var p = new Program();
// out 参数无需初始化
int a, b;
p.GetValues(out a, out b);
Console.WriteLine($"a={a}, b={b}");
// TryParse 模式
if (p.TryDivide(10, 3, out double res))
Console.WriteLine($"10 / 3 = {res:F2}"); // 3.33
}
}
}
C# 7.0 以降では、呼び出し時に内联声明out変数はコードをより簡潔にします:
// C# 7.0+ 内联声明
if (int.TryParse("123", out int number))
Console.WriteLine($"解析成功:{number}");
3. 再帰メソッド
再帰(Recursion)とは、メソッドが调用自身。各再帰メソッドには2つの要素が必要です。
- 基准条件(Base Case):再帰を終了する条件で、無限再帰を防ぎます。
- 递归步骤(Recursive Step):問題をより小さな部分問題に分解します。
代表的な例——階乗の計算 $$n! = n \times (n-1)!$$:
实例
namespace RecursionDemo
{
class Program
{
// 递归计算阶乘
public int Factorial(int n)
{
// 基准条件:0! = 1,1! = 1
if (n <= 1)
return 1;
// 递归步骤:n! = n × (n-1)!
return n * Factorial(n - 1);
}
static void Main(string[] args)
{
var p = new Program();
Console.WriteLine($"6! = {p.Factorial(6)}"); // 720
Console.WriteLine($"7! = {p.Factorial(7)}"); // 5040
Console.WriteLine($"8! = {p.Factorial(8)}"); // 40320
}
}
}
6! = 720 7! = 5040 8! = 40320
再帰呼び出しの展開プロセス:
Factorial(4) = 4 × Factorial(3) = 4 × 3 × Factorial(2) = 4 × 3 × 2 × Factorial(1) = 4 × 3 × 2 × 1 = 24
注意:再帰の深さが大きすぎると、
StackOverflowException。パフォーマンスが重要なシナリオでは、ループ実装への変更を検討してください。
4. メソッドのさらなる特徴
4.1 デフォルトパラメータと名前付きパラメータ
C#では、パラメータに設定できます默认值、呼び出し時にこれらのパラメータを省略できます。組み合わせることで命名参数、一部のパラメータをスキップして後続のパラメータだけを指定することもできます。
实例
namespace MethodFeatures
{
class Program
{
// デフォルト引数:power のデフォルトは 2
static double Power(double baseNum, int power = 2)
{
double result = 1;
for (int i = 0; i < power; i++)
result *= baseNum;
return result;
}
// 多个默认参数
static void PrintInfo(string name, int age = 18, string city = "未知")
{
Console.WriteLine($"{name}, {age}岁, {city}");
}
static void Main(string[] args)
{
// 使用默认参数
Console.WriteLine(Power(3)); // 9.0(使用默认 power=2)
Console.WriteLine(Power(3, 3)); // 27.0
// 命名参数:跳过 age,只指定 city
PrintInfo("小明", city: "北京");
// 输出:小明, 18岁, 北京
// 命名参数可以不按顺序
PrintInfo(city: "上海", name: "小红", age: 25);
// 输出:小红, 25岁, 上海
}
}
}
4.2 式本体メソッド
メソッド本体が1つのステートメントだけの場合は、=>簡略化した書き方(C# 6.0+):
// 传统写法
public int Add(int a, int b)
{
return a + b;
}
// 表达式体写法(等价)
public int Add(int a, int b) => a + b;
4.3 方法重载(Overloading)
同じクラス内には同名の複数のメソッドを持つことができる、パラメータリストが異なる限り(パラメータの型、数、または順序が異なる):
实例
namespace MethodFeatures
{
class Calculator
{
// 重载 1:两个 int 相加
public int Add(int a, int b) => a + b;
// 重载 2:三个 int 相加
public int Add(int a, int b, int c) => a + b + c;
// 重载 3:两个 double 相加
public double Add(double a, double b) => a + b;
static void Main(string[] args)
{
var calc = new Calculator();
Console.WriteLine(calc.Add(1, 2)); // 3(调用重载 1)
Console.WriteLine(calc.Add(1, 2, 3)); // 6(调用重载 2)
Console.WriteLine(calc.Add(1.5, 2.5)); // 4.0(调用重载 3)
}
}
}
小结
| 特性 | 语法 | 说明 |
|---|---|---|
| 定义方法 | int Add(int a, int b) { ... } |
戻り値の型、メソッド名、パラメータを指定します。 |
| 无返回值 | void DoSomething() { ... } |
void値を返さないことを示します |
| 按值传递 | void Foo(int x) |
デフォルトの方式では、仮引数を変更しても実引数には影響しません。 |
| 引用传递 | void Foo(ref int x) |
共有メモリであり、変更は実引数に反映されます。 |
| 输出参数 | void Foo(out int x) |
メソッド内で必ず代入する必要があり、複数の値を返すことができます。 |
| 默认参数 | void Foo(int x = 10) |
呼び出し時に省略でき、デフォルト値が使用されます。 |
| 命名参数 | Foo(city: "北京") |
パラメータ名で指定でき、順序に従う必要はありません。 |
| 表达式体 | int Add(int a, int b) => a + b; |
単行メソッドの簡略表記(C# 6.0+) |
| 方法重载 | 同名でパラメータが異なる | コンパイラはパラメータリストに基づいて自動的に選択します。 |