views:

143

answers:

6

Im programming in C#.NET. I want to create a nested class that can access members of the instance that created it but I can't seem to figure out how.

This is what I want to do:

Car x = new Car()
x.color = "red";
x.Door frontDoor = new x.Door();
MessageBox.Show(frontDoor.GetColor());    // So I want the method GetColor of the class Front Door to be able to access the color field/property of the Car instance that created it.

How do I do it? I tried nesting the Door class inside the Car class but it can't access the members of the Car class that way. Do I need to make Car inherit the door class or something?

+5  A: 

The easiest way is to give the Door type a reference back to the Car which created it.

For example:

class Car { 
  public string color;
  public Door Door() { return new Door(this); }
  class Door { 
    Car owner;
    Door(Car owner) { this.owner = owner; }
    string GetColor() { return owner.color; }
  }
}
JaredPar
-1 This is making the DOOR object dependent on the CAR object. This might work fine until you need to put your DOOR in a TRUCK object.
Jeffrey Hines
public Door() { return new Door(this); } // at line# 3. can you please explain, what is this doing ?
Asad Butt
I agree with the changes you made, but don't like that you left Door nested in the Car class, for the reasons I mentioned in a comment on original question.
Brian
@Asad: Nothing, it doesn't compile. And I'm not sure what he was trying to do there, either.
Brian
@Jared: I replaced your weird line of code with one that works. It is perhaps not what you intended, but that line isn't relevant to the OP's question, won't compile, and is confusing.
Brian
@Jeffrey: True, but I think creating an IVehicle interface is a bad idea until you know you'll actually **have** truck objects. Creating unnecessary indirection hurts maintainability. The IVehicle change will be reasonably easy to make in the future, but it's too early to do so now.
Brian
STW
@Brian, i rolled back your edit. I agree, there is likely more than 1 door but based on the user sample I can only assume there is 1 door.
JaredPar
@Jeffrey, so you're downvoting me because the user gave a bad sample scenario? Downvote the user for having a bad design, not me for giving a correct solution to it.
JaredPar
@Yooder - It's a thought, but also what if you need a door, but you don't have a car that it's attached to.
Jeffrey Hines
@JaredPar - We should be leading the user to a good design as well as a correct answer. This question is as much of a design question as it is a coding question. Giving the user a correct solution that leads to a crappy design isn't going to do him any good.
Jeffrey Hines
@JaredPar: Yes, but your version of the code doesn't compile. You basically stuck a Door constructor in the Car function or something. My edit's motivation was to remove nonsense code.
Brian
Can you guys take a look again? I added more detail to the quesiton
Jordan S
+1  A: 

This really is not a nested class, but rather an object of type Door referenced by a property on an object of typeCar. As references are inherently one-way in C# (and most other object oriented languages), you will need to add a reference in the other direction as well, in order to be able to do what are are trying to.

Here is one possible implementation: Add a constructor to Door, accepting a reference to a Car as parameter. The constructor should save the reference in a private readonly field. In the GetColor() method, use the reference to get the color of the Car instance.

Then, consider replacing the GetColor() with a get-only Car property on Door. Depending on the relationship in your real classes (I assume you are not really modelling cars), this might or might not be preferable.

Jørn Schou-Rode
+2  A: 

This is not generally something you would want to do in a well designed object model.

The DOOR is a component of the CAR object, but should not have a dependency on the CAR object. You should pass the color of the CAR into the DOOR either through the constructor or via setter Property of the DOOR.

Jeffrey Hines
It is perfectly reasonable for a component of an object to know about its parent.
Brian
@Brian - In a generic sense you are correct. I would define an Interface IVehicle and pass that to the contructor of Door.
Jeffrey Hines
@Jeffrey: Oh, I totally agree that using nesting to get access to car's private variables is horrible. I was just saying being able to call GetColor() on the parent is not unreasonable.
Brian
A: 

If you want to be able to access the private members of Car in the door class you need to use inheritance, if you just want to access the public members of Car inside the Door class you can use Composition

Like this:

public class Car
    {
        public string Color;
    }

    public class Door
    {
        public string T;

        public Car C;
    }

Although this is not really a logical approach. It should be that there is a Door property inside the Car class.

Tony
A: 

I'd make the Door class take a Func<Color> in its constructor and the Car class can pass it's GetColor() method through that:

public class Car
{
    private class Door
    {
        public Door(Func<Color> getColourFunc)
        {
        }
    }
}
Lee
+2  A: 

I dont think the door should have any reference to the car at all. The relationship should be model as an association - "owns a" relationship. The car should owns the car door, and even responsible for creating the doors when the car is created. The constructor of the door should take in a parameter to say what colour of door to create e.g door = new Door(this.Colour); whereby 'this' is the reference to the current car object. If you think about it logically, I can change the car colour to blue and my door colour will be changed along with that. However, if I decided to have the door(s) colour to red, it is not necessary that the car colour has to change.

Fadrian Sudaman