CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    May 2011
    Posts
    4

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

  2. #2
    Join Date
    May 2011
    Posts
    4

    Re: Passing arguments

    Using .NET 3.5.

  3. #3
    Join Date
    Jun 2008
    Posts
    2,477

    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.

  4. #4
    Join Date
    May 2011
    Posts
    4

    Re: Passing arguments

    Thank you. Is there any way to only copy contents of the object?

  5. #5
    Join Date
    May 2011
    Posts
    4

    Re: Passing arguments

    Made it with http://www.codeproject.com/KB/cs/ObjectCloner.aspx. Thanks for the info.

  6. #6
    Join Date
    May 2007
    Posts
    1,546

    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
  •  





Click Here to Expand Forum to Full Width

Featured