2010-05-18 87 views
2

我在City类中有这个方法。它应该创建一个基于对象的一个​​新的城市,该方法适用于:对“this”修饰符有问题

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的类型是“点”,它有两个领域 - X,Y。 Point类中的Move方法有助于更改CityCenter的位置。它看起来像这样:

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

会发生什么是新对象c和现有城市对象都被更改。我认为“this”修饰符也适用于现有对象...

如何利用Move方法而不引起此行为? 注意:这是一个封闭的API,所以我只能将私有方法添加到项目中。

+1

浅拷贝,也许? – 2010-05-18 16:43:49

+2

这可能有助于将代码发布在城市(城市c){}' – 2010-05-18 16:44:46

+1

您可以发布“City(City c)'构造函数的代码吗?我怀疑它创建了一个浅拷贝,所以'CityCenter'属性指向相同的'Point'实例。 – dtb 2010-05-18 16:46:28

回答

1

我的猜测是Point是一个类,所以你正在共享对同一个点实例的引用。您将需要创建Point的新实例并将其指定给新City.CityCenter

4

我怀疑City c=new City(this);正在创造一个克隆当前城市,这意味着他们都共享同一个Point对象(如果该点是一个类,而不是一个结构只能是真实的)。

您可以改为City c=new City();吗?

+0

取决于是否有效,您可能还需要为您的新城市创建一个新城市中心... c.CityCenter = new CityCenter(); – BoxOfNotGoodery 2010-05-18 16:46:45

2

问题是(几乎可以肯定),两个城市都有对同一个Point对象的引用。当您更改对象时,通过这两个引用可以看到该更改。选项:

  • 创建一个新的Point对象,当你克隆城市
  • 创建点的值类型(让一个独立的副本是由
  • 创建点不可变型和改变Move返回一个点与相关的变更进行

(或以上的一些组合...)

它SOU对我来说像Point应该可能是一个值类型(结构)。请注意,结构体应该几乎总是是不可变的。

首先有一个newCity实例方法似乎有些奇怪 - 新城市对旧城区意味着什么关系?你为什么不创建一个完全独立的城市?

+0

我不应该感到惊讶的是最好的建议来自Jon Skeet :)我同意Point应该是不可变的。 – 2010-05-18 16:55:53

+0

好吧,它是一个给定的API,所以我不能改变它:( 的原因是这样的话,这个newCity方法将创建一个新城市,基于给定城市名称的变化,城市中心将根据dX ,dY – 2010-05-18 16:58:56

+0

@ user344246:你有多少不能改变?现在显然已经坏了......鉴于居民区的数量和居民的数量也被确定了,它与原来的数量有多少?只是中央车站? – 2010-05-18 16:59:52