【问题标题】:c# changes value of one object property from otherc# 改变一个对象属性的值
【发布时间】:2016-04-15 17:41:09
【问题描述】:

我正在使用来自其他对象的值创建一个对象。就像这样:

MAP.cs

int[][] map = {......};
Mob m = new Mob(0,0,map);

并调用 Mob 的类函数 Move()

m.Move();

移动函数如下所示:

int xp = (int)Math.Floor(x / 32);
int yp = (int)Math.Floor(y / 32);
int[] result = lookForClosest(xp, yp);
this.nextX = result[1];
this.nextY = result[0];
map[this.nextY][this.nextX] = 1;

在另一个类(MainWindow)中使用 DispatcherTimer 调用函数 此应用程序的结果是更改了 MAP 类中的地图属性。唯一的改变应该是在 Mob 对象的 map 属性中。有什么解释和可能的解决方法吗?

【问题讨论】:

  • 您是否尝试过将map 数组的副本传递给Mob 构造函数?

标签: c# pass-by-reference pass-by-value


【解决方案1】:

数组是引用类型,所以当你调用

Mob m = new Mob(0,0,map);

您正在将数组的引用传递给Mob 构造函数,并且您对Mob 类中的数组所做的任何更改都将反映在源数组中。您可以通过以下两种方式之一进行更改:

  1. 在将数组传递给Mob 类之前克隆数组,或者
  2. Mob 构造函数中克隆数组。

从所有权的角度来看,问题是 - 客户应该期望看到对数组的更改,还是数组更像是可以在类中修改的“种子”输入? p>

还请注意,您有一个 数组 数组,因此您不仅需要关闭“外部”数组,还需要关闭其中的每个数组:

public T[][] Clone<T>(T[][] source)
{
    T[][] output = new T[source.Length][];
    for(int i=0; i<source.Length; i++)
        output[i] = (T[])source[i].Clone();

    return output;
}

或者如果您对 Linq 感到满意:

public T[][] Clone<T>(T[][] source)
{
    return source.Select(a => (T[])a.Clone()).ToArray();
}

【讨论】:

  • “种子”。我推断它通过了引用,但是应该使用 for 循环克隆数组,还是有更好的方法?
  • 定义“更好”。 for 循环非常好,或者您可以使用 Linq 查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 2016-06-03
  • 1970-01-01
  • 2016-10-04
相关资源
最近更新 更多