-
May 23rd, 2011, 08:09 PM
#1
Passing arguments
Hello, I'm new to C# and have a problem with argument passing. Every time I pass an object, get some values from it and modify them in a new object, the passed object changes.
Code:
ShipModel first = new ShipModel("1x4", new int[,] {{0,0},{0,1},{0,2},{0,3}});
Ship a1 = new Ship(5, 5, first, false);
Ship a2 = new Ship(5, 5, first, true);
Ship a3 = new Ship(5, 5, first, true);
The code above outputs:
Code:
Inherited... 1x4 @ 0:0 0:1 0:2 0:3
Before moving... 1x4 @ 0:0 0:1 0:2 0:3
After moving... 1x4 @ 5:5 5:6 5:7 5:8
Inherited... 1x4 @ 5:5 5:6 5:7 5:8
Before moving... 1x4 @ 5:5 5:6 5:7 5:8
After moving... 1x4 @ 10:10 10:11 10:12 10:13
Inherited... 1x4 @ 10:10 10:11 10:12 10:13
Before moving... 1x4 @ 10:10 10:11 10:12 10:13
After moving... 1x4 @ 15:15 15:16 15:17 15:18
The initial model is being changed every time a ship is created. the initial coordinates (which should be constant) increases with every adjust(); Tried sealing the model class, did not help.
Code:
public Ship(int xCoord, int yCoord, ShipModel m, bool rotate)
{
x = xCoord; this.y = yCoord;
// inherits coordinates and name from the model
this.coordinates = new List<int[]>(m.getCoords());
this.name = new String(m.getName().ToCharArray());
Console.WriteLine("Inherited... " + this.ToString());
if (rotate) this.rotate();
this.adjust();
}
private void adjust()
{
// moves the ship
Console.WriteLine("Before moving... " + this.ToString());
for (int i = 0; i < this.coordinates.Count; i++)
{
this.coordinates[i][0] += this.x;
this.coordinates[i][1] += this.y;
this.coordinates[i][2] = 0;
}
Console.WriteLine("After moving... " + this.ToString());
}
Code:
class ShipModel
{
private List<int[]> coordinates = new List<int[]>();
private String name;
public ShipModel() { }
public ShipModel(String name, int[,] coordinates)
{
this.name = name;
for (int i = 0; i < (coordinates.Length / 2); i++)
{
this.coordinates.Add(new int[] { coordinates[i, 0], coordinates[i, 1], 0 });
}
}
public String getName()
{
return this.name;
}
public List<int[]> getCoords()
{
return this.coordinates;
}
}
-
May 23rd, 2011, 08:12 PM
#2
-
May 23rd, 2011, 10:20 PM
#3
Re: Passing arguments
Because when you pass a reference to a method you are not passing a copy of the object itself, you are passing a copy of the reference, i.e., any modifications to the original object will be persisted. If you want copy semantics you should use a struct instead of a class, but be warned that, even then, references maintained by the struct will be copied, but not what they refer to (i.e., your List member will be copied, but only the reference, not the contents of the List itself).
On a side note, declaring a class sealed means only that it cannot be inherited from, it has nothing to do with copy semantics.
-
May 24th, 2011, 05:25 AM
#4
Re: Passing arguments
Thank you. Is there any way to only copy contents of the object?
-
May 24th, 2011, 06:11 AM
#5
-
May 24th, 2011, 07:58 AM
#6
Re: Passing arguments
As long as performance is acceptable that would work just fine. If not, you could always call the MemberwiseClone on your class. It creates a new instance of your class and copies the values of the fields to the new instance. If you have any reference fields in your class you'll also need to memberwise clone them and replace the reference on the new object. If you don't, you'll end up with the same object reference stored in multiple places which is what caused your original problem.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|