2012-07-13 17 views
5

この例のために、Clue™のダンプダウンゲームを行っているとします。私たちには、大邸宅の各部屋のクラスと、各部屋の容疑者と武器のサブクラスがあります。ネストされたクラスがあった後、しかし - Room[i] = new Room("Conservatory", 7, 3);クラスとそのネストされたクラスの1つのコンストラクタ

public Room(string Name, int Width, int Height) 
{ 
    this.Name = Name; 
    this.Width = Width; 
    this.Height = Height; 
} 

は、のような単純なものに使用される部屋の初期化:

class Room 
{ 
    public string Name; 
    public int Width; 
    public int Height; 
    // and so on... 

    public class Suspect 
    { 
    public string Name; 
    public bool isPurple; 
    } 

    public class Weapon 
    { 
    public string Name; 
    public bool IsMetal; 
    } 
} 

容疑者と武器のクラスを追加する前に、ルームのコンストラクタは次のように見えた:何かのようにそれらの初期化は、メインクラスの共有コンストラクタによって処理できますか?次のようなものがあります。

Room[i] = new Room("Library", 8, 5, "Professor Plum", true, "Candlestick", true); 

同様の設定の例はありません。どうすればこれを達成できますか?

+0

このようなParentClass.ChildClassを探していますか?childClass = new ParentClass.ChildClass(); – HatSoft

+7

ネストされたクラスは、その親クラスと特別な関係はありません。あなたはそれを非公開と宣言し、それを完全に隠すことができることを除いて。そして、それは外部クラスのプライベートメンバーにアクセスできます。つまり、「共有コンストラクタ」が理にかなっているシナリオはありません。また、文字クラスを部屋のプライベートな実装の詳細にすることも意味がありません。 –

+0

例は見つかりません。なぜなら、 "Professor Plum"がSuspect.Nameプロパティの値として使用されるはずです。 – Steve

答えて

7

コンストラクタに非常に多くのパラメータがあるのに対して、このようなことはしないでください。ネストされたクラスはメインクラスに導入さ

public class Room 
{ 
    public Room(Suspect suspect, Weapon weapon) 
    { 
     SuspectInRoom = suspect; 
     WeaponInRoom = weapon; 
    } 

    public Suspect SuspectInRoom { get; set; } 
    public Weapon WeaponInRoom { get; set; } 
} 

// Example usage: 

Suspect coronelCustard = new Suspect("Coronel Custard"); 
Weapon musket = new Weapon("Musket"); 

Room someRoom = new Room(coronelCustard, musket); 

// Then your room can be used to access all sorts of data. 

Console.WriteLine(someRoom.SuspectInRoom.Nickname); // "The Big Kahuna" 
Console.WriteLine(someRoom.WeaponInRoom.AttackDamage); // "20" 

は、その 初期化は主 クラスと共有コンストラクタを介して処理することができますか?あなたのネストされたクラスは、あなたがそれを行うことができますpublicコンストラクタを持っている場合は最終的に私は...同じ 行にすべての3つのクラスを初期化するために

を期待したいです。

例:

Room someRoom = new Room(new Suspect("Colonel Custard"), new Weapon("Musket")); 

はしかし、それはこのように物事を行うためのコードのにおいのようなものです。すでに作成され、インスタンス化されたメンバーをコンストラクタ呼び出しで使用する方がよいでしょう。いずれにせよ個人的な選択です。

+0

+1。あなたのコードでは、ルームには名前がないことに注意してください。これは、OPのコンストラクタの場合とは異なります。 – ken2k

+0

@ ken2k:ああ、彼はこれを彼の必要に合わせて調整する必要があるだろう。彼のクラスをよりうまく編成する方法を説明したいだけです。 –

+1

私は、武器の「攻撃ダメージ」が重要だったClueのバージョンをプレイしたことは一度もありません。結局のところ、 "攻撃された"唯一の人はゲームの始めに死んでいる。 ;) –

5

あなたも、ちょうど初期化子を使用して... constructores必要はありません。

var room = new Room { Name = "Library", 
         Width = 7, 
         Height = 3, 
         Suspect = new Suspect { Name = "Professor Plum", 
               PlaysCroquet = false }, 
         Weapon = new Weapon { Name = "Candlestick", 
               IsShiny = true } 
         }; 
+0

疑惑と武器は、彼の例ではフィールドではなく、ネストされたクラスです。 –

+1

あなたは私の考えを盗んだ! ;) –

+0

比喩は私のためにちょっと分かりませんでした。私がコンストラクタを使用していた理由は、フィールドの将来のランダム化のためでした。プラム教授が必ずしも図書館に行くとは限りません。 – 4444

2

これを行うための簡単な方法は、容疑者と武器クラスのpublicコンストラクタを与えることですので、彼らは外でインスタンス化することができますルームクラス(クラスは公に宣言されているので、これは受け入れ可能とみなします)。

Roomコンストラクタは、SuspectとWeaponへの参照を取得できます。これにより、以前のある時点でSuspectオブジェクトとWeaponオブジェクトを柔軟に作成し、作成時にRoomに渡すことができます。これにより、RoomクラスのコンストラクタがSuspectクラスとWeaponクラスのプロパティについて知る必要がなくなります。それらに追加する)。

簡潔にするために、あなたはまだそのような単一のライン内のすべてのオブジェクト、構築することができます。自分自身で

Room[i] = new Room("Library", 8, 5, new Suspect("Professor Plum", false), new Weapon("Candlestick", true)); 
1

クラスを初期化する必要はありません、メンバーです。

コンストラクタに渡す引数とコンストラクタで初期化するクラスのメンバーには正式な制限はありません。フィールドまたはプロパティの型がネストされたクラスである場合、コンストラクタの観点からはintまたはstringと異なることはありません*

*:非公開のネストされたクラスの型のメンバは、他のメソッドまたはコンストラクタで初期化する必要があります。パブリックの読み書きプロパティは、クラスのインスタンスで直接設定することもできます。

関連する問題