2012-07-13 106 views
5

爲了這個例子的緣故,假設我們正在做一個虛擬的遊戲Clue™。我們爲豪宅中的每個房間設置一個班級,並在每個房間中爲嫌疑人和武器分配一個班級。喜歡的東西:一個類和它的嵌套類的構造函數

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; 
    } 
} 

之前將犯罪嫌疑人與武器類,房間構造看起來是這樣的:

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

初始化以前那樣簡單的房間:Room[i] = new Room("Conservatory", 7, 3); - 但嵌套類是後介紹,他們的初始化可以通過與主類共享構造函數來處理?類似於:

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

我似乎無法找到類似設置的任何示例。我怎樣才能做到這一點?

+0

你在找這樣的事情ParentClass.ChildClass childClass =新ParentClass.ChildClass(); – HatSoft 2012-07-13 15:48:11

+7

嵌套類與其父類沒有特別的關係。除了你可以聲明它是私人的,因此完全隱藏它。而且它可以訪問外部類的私人成員。就是這樣,沒有一個「共享構造函數」有意義的場景。將角色類作爲房間的私人實現細節也沒有意義。 – 2012-07-13 15:48:12

+0

你沒有發現任何的例子,因爲沒有人能寫出這樣的例子,編譯器怎麼知道「梅花教授」應作爲價值的Suspect.Name財產? (我想,這是你的意圖) – Steve 2012-07-13 15:48:22

回答

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" 

當嵌套類被引入到一個主類,可以將其 初始化時通過一個共享的構造與主 類處理?最後,我倒是希望來初始化在同一 線的所有三個類別...

如果您的嵌套類有一個公共構造函數,你可以做到這一點。

例子:

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

但是,它是一種代碼氣味這樣做事的。最好在構造函數調用中使用已創建和實例化的成員。這是一種個人選擇。

+0

+1。但請記住,在你的代碼中,一個房間可以沒有名字,這與OP的構造函數不同。 – ken2k 2012-07-13 15:51:18

+0

@ ken2k:哦,是的,他會需要調整這個他的需要。我只想說明如何更好地組織他的課程。 – 2012-07-13 15:52:02

+1

我從來沒有玩過線索版本,其中武器的「攻擊傷害」很重要。畢竟,唯一一個「受到攻擊」的遊戲在遊戲開始時就已經死亡。 ;) – 2012-07-13 16:07:09

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

在他的例子中,suspect和weapon不是字段,它們是嵌套類。 – 2012-07-13 15:50:09

+1

你偷了我的主意! ;) – 2012-07-13 15:50:11

+0

這個比喻對我來說有點崩潰 - 我使用構造函數的原因是爲了將來的字段隨機化。梅教授不一定去圖書館。 – 4444 2012-07-13 15:52:00

2

一個簡單的方法來做到這一點是給犯罪嫌疑人與武器類的公共構造函數,這樣他們就可以被實例化的外Room類(我認爲這是可以接受的,因爲這些類是公開的)。

房間構造函數可以引用可疑和武器。這使您可以靈活地創建Suspect和Weapon對象,並將它們傳遞到構建的房間中 - 同時也可以防止Room類構造函數不必瞭解Suspect和Weapon類的屬性(並且在您需要時修改添加到他們)。

爲了簡便起見,仍然可以構建所有對象在一行,就像這樣:

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

類本身並不需要被初始化,成員。

對於傳遞給構造函數的參數以及在構造函數中初始化的類的哪些成員沒有形式上的限制。如果字段或屬性的類型正好是嵌套類 - 它沒有比intstring不同的看法*構造的觀點。

*:唯一的潛在區別是非公共嵌套類的成員必須在其他方法或構造方法中初始化,而公共讀/寫屬性也可以直接在類的實例上直接設置。