4444 4444 - 4 days ago 5
C# Question

One Constructor for a Class and its Nested Classes

For the sake of this example, suppose we're making a dumbed-down game of Clue™. We have a class for each Room in the mansion, and subclasses for the Suspect and Weapon in each Room. Something like:

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


Before adding the Suspect and Weapon classes, the Room constructor looked something like:

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


Initializing a room used to be as simple as:
Room[i] = new Room("Conservatory", 7, 3);
- but after the nested classes were introduced, can their initialization be handled through a shared constructor with the main class? Something like:

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


I can't seem to find any examples of a similar setup. How can I accomplish this?

Answer

Instead of having your constructor have so many parameters, why not do something like this?

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"

When nested classes are introduced to a main class, can their initialization be handled through a shared constructor with the main class? Eventually I'd hope to initialize all three classes in the same line...

If your nested class has a public constructor you can do that.

Example:

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

But, it's kind of a code smell to do things this way. It's better to use already created and instantiated members in constructor calls. It's a personal choice either way.

Comments