チュートリアル

C#基礎:メソッド

CSharp入門メソッド
広告エリア

メソッドの定義

public class Calculator
{
    // 基本的なメソッド
    public int Add(int a, int b)
    {
        return a + b;
    }

    // 戻り値なし
    public void PrintMessage(string message)
    {
        Console.WriteLine(message);
    }

    // 式本体メソッド(1行の場合)
    public int Multiply(int a, int b) => a * b;

    // 静的メソッド
    public static int Max(int a, int b) => a > b ? a : b;
}

// 使用
var calc = new Calculator();
int sum = calc.Add(3, 5);
calc.PrintMessage("Hello");

// 静的メソッドはクラス名で呼び出し
int max = Calculator.Max(10, 20);

引数

オプション引数とデフォルト値

public void Greet(string name, string greeting = "こんにちは")
{
    Console.WriteLine($"{greeting}、{name}さん");
}

Greet("太郎");              // "こんにちは、太郎さん"
Greet("花子", "おはよう");  // "おはよう、花子さん"

名前付き引数

public void CreateUser(string name, int age, string email = "")
{
    // ...
}

// 名前を指定して呼び出し
CreateUser(name: "太郎", age: 25);
CreateUser(age: 30, name: "花子");
CreateUser("次郎", email: "jiro@example.com", age: 20);

params(可変長引数)

public int Sum(params int[] numbers)
{
    return numbers.Sum();
}

int result1 = Sum(1, 2, 3);           // 6
int result2 = Sum(1, 2, 3, 4, 5);     // 15
int result3 = Sum(new[] { 10, 20 }); // 30

ref, out, in

// ref - 参照渡し(変更可能)
public void Double(ref int value)
{
    value *= 2;
}

int num = 5;
Double(ref num);
Console.WriteLine(num);  // 10

// out - 出力引数(必ず値を設定)
public bool TryParse(string s, out int result)
{
    return int.TryParse(s, out result);
}

if (TryParse("123", out int value))
{
    Console.WriteLine(value);  // 123
}

// in - 読み取り専用参照渡し
public double Distance(in Point p1, in Point p2)
{
    // p1, p2 は変更不可
    return Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
}

戻り値

タプルで複数の値を返す

public (int min, int max) GetMinMax(int[] numbers)
{
    return (numbers.Min(), numbers.Max());
}

var result = GetMinMax(new[] { 3, 1, 4, 1, 5 });
Console.WriteLine($"Min: {result.min}, Max: {result.max}");

// 分解
var (min, max) = GetMinMax(new[] { 3, 1, 4, 1, 5 });

ref戻り値

public ref int GetReference(int[] arr, int index)
{
    return ref arr[index];
}

int[] numbers = { 1, 2, 3 };
ref int second = ref GetReference(numbers, 1);
second = 20;
Console.WriteLine(numbers[1]);  // 20

メソッドのオーバーロード

public class Printer
{
    public void Print(string message)
    {
        Console.WriteLine(message);
    }

    public void Print(int number)
    {
        Console.WriteLine(number);
    }

    public void Print(string message, int times)
    {
        for (int i = 0; i < times; i++)
        {
            Console.WriteLine(message);
        }
    }
}

var printer = new Printer();
printer.Print("Hello");
printer.Print(42);
printer.Print("Hi", 3);

ローカル関数

public int Factorial(int n)
{
    // ローカル関数
    int Calculate(int x)
    {
        if (x <= 1) return 1;
        return x * Calculate(x - 1);
    }

    if (n < 0) throw new ArgumentException("負の数は無効");
    return Calculate(n);
}

// 静的ローカル関数(外部変数をキャプチャしない)
public int Process(int[] numbers)
{
    static int Square(int x) => x * x;
    return numbers.Sum(Square);
}

拡張メソッド

既存の型にメソッドを追加します。

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string s)
    {
        return string.IsNullOrEmpty(s);
    }

    public static string Reverse(this string s)
    {
        char[] chars = s.ToCharArray();
        Array.Reverse(chars);
        return new string(chars);
    }

    public static int WordCount(this string s)
    {
        return s.Split(new[] { ' ', '\t', '\n' },
            StringSplitOptions.RemoveEmptyEntries).Length;
    }
}

// 使用
string text = "Hello World";
Console.WriteLine(text.Reverse());    // "dlroW olleH"
Console.WriteLine(text.WordCount());  // 2

string empty = "";
Console.WriteLine(empty.IsNullOrEmpty());  // true

デリゲートとラムダ式

// デリゲート型
public delegate int MathOperation(int a, int b);

// Funcを使用
Func<int, int, int> add = (a, b) => a + b;
Func<int, int, int> multiply = (a, b) => a * b;

Console.WriteLine(add(3, 5));       // 8
Console.WriteLine(multiply(3, 5));  // 15

// Actionを使用(戻り値なし)
Action<string> print = message => Console.WriteLine(message);
print("Hello");

// Predicateを使用(boolを返す)
Predicate<int> isPositive = n => n > 0;
Console.WriteLine(isPositive(5));   // true
Console.WriteLine(isPositive(-3));  // false

実践例:バリデーション

public static class Validator
{
    public static bool IsValidEmail(this string email)
    {
        if (string.IsNullOrWhiteSpace(email)) return false;

        try
        {
            var addr = new System.Net.Mail.MailAddress(email);
            return addr.Address == email;
        }
        catch
        {
            return false;
        }
    }

    public static bool IsValidPhoneNumber(this string phone)
    {
        var cleaned = new string(phone.Where(char.IsDigit).ToArray());
        return cleaned.Length >= 10 && cleaned.Length <= 11;
    }

    public static (bool isValid, List<string> errors) ValidateUser(
        string name, string email, string phone)
    {
        var errors = new List<string>();

        if (string.IsNullOrWhiteSpace(name))
            errors.Add("名前は必須です");
        else if (name.Length < 2)
            errors.Add("名前は2文字以上必要です");

        if (!email.IsValidEmail())
            errors.Add("メールアドレスが無効です");

        if (!phone.IsValidPhoneNumber())
            errors.Add("電話番号が無効です");

        return (errors.Count == 0, errors);
    }
}

// 使用
var (isValid, errors) = Validator.ValidateUser(
    "太郎",
    "taro@example.com",
    "090-1234-5678"
);

if (!isValid)
{
    foreach (var error in errors)
    {
        Console.WriteLine(error);
    }
}

まとめ

  • メソッドは戻り値型 メソッド名(引数)で定義
  • 式本体=>で1行メソッドを簡潔に
  • オプション引数と名前付き引数で柔軟な呼び出し
  • ref/out/inで参照渡し
  • タプルで複数の値を返す
  • 拡張メソッドで既存型を拡張
  • Func/Action/Predicateでデリゲート

次回は配列とコレクションについて学びます。

広告エリア