Sat chua
Sat chua

Reputation: 3

Change in original array but the clone array stay the same; C#

Here is my original array called "gridPlacement"

Original Array: "gridPlacement"

Clone Array: "p1"

class gridMemory
{
    static public string[] gridPlacement =
        new string[9] {"x", "b", "c", "h", null, null, null, null, null };
}

Here is my cloned array called "p1". Although, it is only consist some part of the original array.

class handleWinLost
{
    static public string[] p1 = new string[3] {
        gridMemory.gridPlacement[0],
        gridMemory.gridPlacement[3]
        gridMemory.gridPlacement[2]
    };
}

When I made changes to the index 2 of original array from "c" to "b". Array p1 last element stay the same, "c". Even though, gridMemory.gridPlacement[2] which is p1[2].

Upvotes: 0

Views: 118

Answers (3)

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

You intend to run this line of code:

gridMemory.gridPlacement[2] = "b";

Ultimately, strings are reference types with some special treatment to give them value semantics. This means initially you have two reference variables — gridMemory.gridPlacement[2] and p1[2] — that both refer to the same string object in memory, which happens to have a value of "c".

That is, we have the variable gridMemory.gridPlacement[2], whose value is a reference to some address in memory, and we have the variable p1[2] whose value is a different reference to the same address in memory. This is because the reference in gridMemory.gridPlacement[2] was assigned to p1[2]. However, this assignment copies the reference so you now have two references. They happen to target the same memory, but they are not the same reference.

So now we run the line of code. What it does is create a new string object in memory ("b"), and assign a reference to that string object to gridMemory.gridPlacement[2].

At no point is p1[2] ever involved in this line of code. p1[2] has its own reference. This reference still refers to the same memory, which still has a value of "c".

Upvotes: 2

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112279

If you want to reflect changes of the original array, store indexes instead:

public static int[] p1 = new int[3] { 0, 3, 2 };

And then get the values like this:

string value = gridMemory.gridPlacement[p1[i]];

You can also make p1 private and provide a method for the access:

private static int[] p1 = new int[3] { 0, 3, 2 };

public static int PlacementCount => p1.Length;

public static string GetPlacementAt(int index) 
{
    return gridMemory.gridPlacement[p1[index]];
}

and access it like this (in a loop as an example):

for (int i = 0; i < handleWinLost.PlacementCount; i++) {
    string placement = handleWinLost.GetPlacementAt(i);
    Console.WriteLine(placement);
}

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499790

This statement:

static public string[] p1 = new string[3] {
    gridMemory.gridPlacement[0],
    gridMemory.gridPlacement[3]
    gridMemory.gridPlacement[2]
};

... creates an array, and assigns values to the element. Leaving aside the fact that it's a field declaration, it's equivalent to:

string[] p1 = new string[3];
p1[0] = gridMemory.gridPlacement[0];
p1[1] = gridMemory.gridPlacement[3];
p1[2] = gridMemory.gridPlacement[2];

Each of those assignments just evaluates the expression on the right hand side, and copies it to the array element described on the left hand side. It doesn't set up any lasting relationship between say p1[0] and gridMemory.gridPlacement[0]. Any later changes in gridMemory.gridPlacement are completely irrelevant to handleWinLost.p1.

Upvotes: 3

Related Questions