2012-07-13 80 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不同的看法*构造的观点。

*:唯一的潜在区别是非公共嵌套类的成员必须在其他方法或构造方法中初始化,而公共读/写属性也可以直接在类的实例上直接设置。