-2

I'm creating one object by using values from other object.Like that:

MAP.cs

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

And calling Mob's class function Move()

m.Move();

Move function looks like this:

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;

Functions are called using DispatcherTimer in another class(MainWindow) The result of this application is that map property in MAP class is changed. The only change made should be in the Mob object's map property. Any explanation and possible fix?

Berrigan
  • 438
  • 4
  • 23

1 Answers1

1

Arrays are reference types, so when you call

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

You are passing a reference to the array to the Mob constructor, and any changes you make to the array in the Mob class will be reflected in the source array. You can change this one of two ways:

  1. Clone the array before passing it to the Mob class, or
  2. Clone the array within the Mob constructor.

From a ownership perspective, the question is - should clients expect to see changes to the array, or is the array more of a "seed" input that can be modified within the class?

Also note that you have an array of arrays, so you not only need to close the "outer" array, but each of the arrays within it:

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

or if you're comfortable with Linq:

public T[][] Clone<T>(T[][] source)
{
    return source.Select(a => (T[])a.Clone()).ToArray();
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • The "seed one". I deducated that it passes the reference, but should the array be cloned using for loops, or is there any better way? – Berrigan Apr 15 '16 at 17:52
  • 1
    Define "better". A `for` loop is perfectly fine, or you could use a Linq query. – D Stanley Apr 15 '16 at 17:55