オブジェクトを返すメソッドとは?

C# プログラミングでは、クラスとインスタンスを使ったオブジェクト指向が基本です。その一例として「銀行口座(BankAccount)」クラスをサンプルに用います。口座の生成や預金といった身近な操作を例にすることで、オブジェクト返却メソッドの仕組みを直感的に理解できるようになります。


なぜ「銀行口座」をサンプルにするのか?

  1. 身近でイメージしやすいお金の預け入れ・残高照会は、日常的によく行われる操作です。初心者にもなじみがあるため、コードの動作を頭の中でシミュレーションしやすくなります。
  2. 属性と振る舞いがわかりやすい
    • 属性: 口座名義(Owner)、残高(balance)
    • 振る舞い: 預金(Deposit)、残高取得(GetBalance)オブジェクト指向の概念を学ぶ際に、クラスのプロパティやメソッドを明確に意識できます。
  3. 拡張例が豊富将来的には、引き出し機能や利息計算、口座履歴の記録など、さまざまな機能追加パターンを学習できます。

バージョン1:シンプルな口座生成

using System;

namespace ObjectReturnPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 単一の口座を生成し、預金して出力
            BankAccount bankAccount = new BankAccount();
            bankAccount.Owner = "山田太郎";
            bankAccount.Deposit(1000);

            Console.WriteLine($"Owner: {bankAccount.Owner}, Balance: {bankAccount.GetBalance()}");
            // → Owner: 山田太郎, Balance: 1000
        }
    }

    public class BankAccount
    {
        public string Owner { get; set; } = "";
        private int balance = 0;

        public void Deposit(int amount)
        {
            balance += amount;
        }

        public int GetBalance()
        {
            return balance;
        }
    }
}

ポイント

  • Main 内で直接 new BankAccount() を行い、操作を実装。
  • サンプルとして最小限のコード。

ここで、バージョン管理の学習の基礎を見ていきます


バージョン2:日本語表示+コメント追加&複数口座対応

using System;

namespace ObjectReturnPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 1人目の口座を生成
            BankAccount account1 = new BankAccount();
            account1.Owner = "山田太郎";
            account1.Deposit(1000);

            // 2人目の口座を生成
            BankAccount account2 = new BankAccount();
            account2.Owner = "鈴木花子";
            account2.Deposit(5000);

            // 各口座の情報を日本語で表示
            Console.WriteLine($"口座名義: {account1.Owner}、残高: {account1.GetBalance()} 円");
            Console.WriteLine($"口座名義: {account2.Owner}、残高: {account2.GetBalance()} 円");
        }
    }

    /// <summary>
    /// 銀行口座を表すクラス
    /// </summary>
    public class BankAccount
    {
        // 口座名義を保持するプロパティ
        public string Owner { get; set; } = "";

        // 残高を保持する非公開フィールド
        private int balance = 0;

        /// <summary>
        /// 指定した金額を預金する
        /// </summary>
        public void Deposit(int amount)
        {
            balance += amount;
        }

        /// <summary>
        /// 現在の残高を取得する
        /// </summary>
        public int GetBalance()
        {
            return balance;
        }
    }
}

改善点

  • 日本語コメントと XML ドキュメントで可読性向上。
  • 複数口座に対応し、サンプルの汎用性アップ。

バージョン3:オブジェクトを返すメソッド化(ファクトリメソッド導入)

using System;

namespace ObjectReturnPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // メソッドで口座生成~初期預金まで一括処理
            BankAccount account1 = CreateBankAccount("山田太郎", 1000);
            BankAccount account2 = CreateBankAccount("鈴木花子", 5000);

            Console.WriteLine($"口座名義: {account1.Owner}、残高: {account1.GetBalance()} 円");
            Console.WriteLine($"口座名義: {account2.Owner}、残高: {account2.GetBalance()} 円");
        }

        /// <summary>
        /// 銀行口座を生成し、初期預金まで完了したインスタンスを返すファクトリメソッド
        /// </summary>
        static BankAccount CreateBankAccount(string owner, int initialDeposit)
        {
            BankAccount account = new BankAccount();  // インスタンス生成
            account.Owner = owner;                   // オーナー名設定
            account.Deposit(initialDeposit);         // 初期預金
            return account;                          // 完成オブジェクトを返却
        }
    }

    /// <summary>
    /// 銀行口座を表すクラス
    /// </summary>
    public class BankAccount
    {
        public string Owner { get; set; } = "";
        private int balance = 0;

        public void Deposit(int amount) => balance += amount;
        public int GetBalance() => balance;
    }
}

以下のように、両者はまったく同じ動作をします。違いは「書き方(構文)」だけで、コンパイル後の動作(生成されるILコード)も同一です。


1. 構文の違い

書き方構文備考
ブロック式(従来)public void Deposit(int amount)
{
balance += amount;
}
複数行の処理やローカル変数の宣言も可能
式本体メンバーpublic void Deposit(int amount) => balance += amount;単一式(式1つ)のみ記述可C#6.0以降で利用可能

2. 動作の比較

  • 入力パラメーターどちらも int amount を受け取り、クラスフィールド balance に加算します。
  • 戻り値void 型なので戻り値はありません。
  • 例外処理や副作用ブロック式/式本体いずれも同じく balance を変更する副作用を持ちます。

3. コンパイル後の同等性

両者をコンパイルして生成される中間言語(IL)は 同一 です。

これは、式本体メンバーが「単一式メソッド用の構文糖衣(シンタックスシュガー)」に過ぎないためです。


4. どちらを使うべきか

  • 可読性重視
    • 処理が単一の短い式なら、式本体メンバー(=>)の方がシンプルで読みやすい
    • 複数行になる場合や将来処理が増える可能性がある場合は、ブロック式 { … } を使う
  • チームのコーディング規約
    • プロジェクトによっては式本体メンバーの使用を制限している場合もありますので、規約に従いましょう

まとめ

// ブロック式
public void Deposit(int amount)
{
    balance += amount;
}

// 式本体メンバー(C#6.0+)
public void Deposit(int amount) => balance += amount;
  • 動作・生成ILともに同一
  • 好みや可読性、プロジェクト規約で使い分け

以上のとおり、まったく同じ機能を持つ「書き方の違い」だけ、ということです。

大きな改善点

  • 初期化ロジックを CreateBankAccount に集約し、一元管理。
  • Main メソッドはシンプルかつ読みやすく。

まとめ:サンプルから学ぶオブジェクト返却メソッド

  1. 身近な銀行口座 を例にすることで、属性と振る舞いを明確にイメージできる。
  2. 段階的リファクタリング により、コードの再利用性・可読性・保守性が向上。
  3. プロジェクトでは、このパターンをユーザー生成やリソース管理など、さまざまな場面で活用可能。

ぜひ銀行口座サンプルを足がかりに、独自クラスのファクトリメソッドやオブジェクト返却メソッドを実装してみてください!

訪問数 44 回, 今日の訪問数 3回