tags:

views:

91

answers:

3

I have this method in City class. It should create a new city based on the object which the method is applied to:

 public City newCity(string newCityName, int dX, int dY)
    {
        City c=new City(this); //based on a constructor : City(City c){}

        c.CityName=newCityName;
        c.NoOfNeighborhoods=1;
        c.NumOfResidents=0;
        c.CityCenter.Move(dX,dY);

        return c;
    }

CityCenter is of type "Point" which has two fields - x,y. the Move method in Point class is ment to change the CityCenter location. It looks like this:

 public void Move(int dX, int dY)
    {
        this.X = x + dX;
        this.Y = y + dY;
    }

What happens is that the new object,c and the existing City object are both changed. I think that "this" modifier works on the existing object too...

How can I take advantage of the Move method without causing this behavior? Note: this is a closed API, so I can only add private methods to the project.

+4  A: 

I suspect City c=new City(this); is creating a shallow clone of the current City which means they both share the same Point object (could only be true if Point is a class and not a struct).

Can you do City c=new City(); instead?

Daniel Renshaw
Depending on if that works you might also be needing to create a new CityCenter for you new City... c.CityCenter = new CityCenter();
JohnFly
+1  A: 

My guess is that Point is a class, so you are sharing the reference to the same instance of the point. You will need to create a new instance of the Point and assign that to the new City.CityCenter

Chris Taylor
+2  A: 

The problem is (almost certainly) that both cities have a reference to the same Point object. When you change the object, that change is seen through both references. Options:

  • Create a new Point object when you clone the city
  • Make Point a value type (so that an independent copy is made
  • Make Point an immutable type and change Move to return a new Point with the relevant change made

(Or some combination of the above...)

It sounds to me like Point should probably be a value type (a struct). Note that structs should almost always be immutable.

It seems somewhat odd to have a newCity instance method in the first place - what relation is the new city meant to have to the old city? Why aren't you just creating a completely separate city?

Jon Skeet
I shouldn't be surprised that the best advice came from Jon Skeet :) I concur that the Point should be immutable.
Mr. Shiny and New
well, its a given API, so I cannot change it :(the reason for this is so that this newCity method will create a new City based on a given one with the changes of CityName and the CityCenter will be moved according to dX,dY
Guy Z
@user344246: How much can't you change? It's clearly broken at the moment... Given that the number of neighbourhoods and number of residents is set as well, just how much does it have in common with the original? Just the central station?
Jon Skeet
I just need the Central Station x,y to create the new city based on those
Guy Z
Guys! Thank you very much. I got the problem...you've been very helpful :)
Guy Z
@user344246: It's not terribly clear from "newCity" that it really means "just preserve the location of the central station". Why not just have a City constructor which takes a central station to start with?
Jon Skeet