インスタンスデータ vs 静的データ
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 15/70。
静的メンバについて理解したところで、インスタンスデータと静的データのどちらを使用すべきかを明確にしましょう。この決定は、クラスが情報をどのように保存し、共有するかに影響を与えます。
インスタンスデータは各オブジェクトに個別に属します。すべてのオブジェクトが独自のコピーを持ち、1つのオブジェクトへの変更は他のオブジェクトに影響を与えません:
public class BankAccount
{
public string Owner { get; set; } // インスタンス - アカウントごとに固有
public decimal Balance { get; set; } // インスタンス - アカウントごとに固有
}各 BankAccount は、独自の所有者と残高を持っています。異なる口座が異なる人に対して異なる金額を保持するため、これは理にかなっています。
静的データはクラス自体に属し、すべてのインスタンス間で共有されます:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // 静的 - すべてのアカウントで共通
public static int TotalAccounts = 0; // 静적 - すべてのアカウントを追跡
public string Owner { get; set; }
public decimal Balance { get; set; }
}利率はすべてのアカウントに等しく適用されるため、static(静的)にするのが理にかなっています。アカウントの総数カウンターは、個々のアカウントのデータではなく、クラス全体の情報を追跡します。
シンプルなルール:データが特定のオブジェクトを記述している場合は、それをインスタンスにします。クラス全体を記述している場合、または共有されるべき場合は、それをスタティックにします。これらを誤って混在させると、オブジェクト間でデータが予期せず変更されたり、必要なときにアクセスできなかったりするバグにつながります。
チャレンジ
簡単個々のプレイヤーに属するデータと、ゲーム全体で共有されるデータの違いを実演するゲームセッショントラッカーを構築しましょう。
コードを整理するために2つのファイルを作成します:
Player.cs:GameSession名前空間内にPlayerクラスを定義します。各プレイヤーは独自のUsername(string) とScore(int) を持ちます。これらは各プレイヤーに固有のものです。また、クラスはすべてのプレイヤーに適用される情報も追跡する必要があります。全員がプレイしているゲームの名前を格納する静的フィールドGameName(string) と、参加したプレイヤーの総数をカウントする静的フィールドTotalPlayers(int) です。ユーザー名と開始スコアを受け取り、自動的にプレイヤー総数をインクリメントするコンストラクタを含めてください。ゲーム名を設定するための静的メソッドSetGameName(string name)を追加してください。Program.cs: メインファイルで、ゲームをセットアップし、入力に基づいてプレイヤーを作成します。まずゲーム名を設定し、次に2人のプレイヤーを作成して、共有されているゲームデータとともに個々の情報を表示します。
5つの入力を受け取ります:
- ゲーム名
- 1人目のプレイヤーのユーザー名
- 1人目のプレイヤーの開始スコア
- 2人目のプレイヤーのユーザー名
- 2人目のプレイヤーの開始スコア
出力は以下の形式で表示してください:
Game: {GameName}
Player: {Username}, Score: {Score}
Player: {Username}, Score: {Score}
Total Players: {TotalPlayers}例えば、入力が BattleArena, DragonSlayer, 1500, ShadowNinja, 2200 の場合、出力は以下のようになります:
Game: BattleArena
Player: DragonSlayer, Score: 1500
Player: ShadowNinja, Score: 2200
Total Players: 2どのデータがインスタンスベース(プレイヤーごとに異なる)で、どのデータが静的(すべてのプレイヤーで共有される)であるべきかを慎重に考えてください。ゲーム名とプレイヤー総数はセッション全体を表し、ユーザー名とスコアは各個人に固有のものです。
チートシート
各オブジェクトに固有のプロパティには、インスタンスデータを使用します。
public class BankAccount
{
public string Owner { get; set; } // 各口座にはそれぞれの所有者がいます
public decimal Balance { get; set; } // 各口座にはそれぞれの残高があります
}クラスのすべてのインスタンスで共有されるプロパティには、静的データを使用します。
public class BankAccount
{
public static decimal InterestRate = 0.05m; // すべての口座で共通
public static int TotalAccounts = 0; // すべての口座を追跡します
public string Owner { get; set; }
public decimal Balance { get; set; }
}決定ルール: データが特定のオブジェクトを表す場合は、インスタンスデータを使用します。クラス全体を表す場合や共有すべき場合は、静的データを使用します。
自分で試してみよう
using System;
namespace GameSession
{
class Program
{
public static void Main(string[] args)
{
// 入力を読み込む
string gameName = Console.ReadLine();
string username1 = Console.ReadLine();
int score1 = Convert.ToInt32(Console.ReadLine());
string username2 = Console.ReadLine();
int score2 = Convert.ToInt32(Console.ReadLine());
// TODO: static メソッドを使用してゲーム名を設定する
// TODO: 入力データを使用して2つの Player オブジェクトを作成する
// TODO: 要求された形式で出力を表示する
// Game: {GameName}
// Player: {Username}, Score: {Score}
// Player: {Username}, Score: {Score}
// Total Players: {TotalPlayers}
}
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。