How to copy Array of objects, by values?  
Author Message
danni123





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

abstract class AbstractClass
{

public abstract double this[int i]
{
set;
}

}
class Point
{
public double x;
public double y;

}
class ClassA : AbstractClass
{
private Point[] points;


public ClassA(Point[] point_arr)
{
points = (Point[])point_arr.Clone();
}


public override double this[int i]
{
set
{
pointsIdea.y = value;
}
}
}
class ClassB : AbstractClass
{
private Point[] points;

public ClassB(Point[] point_arr)
{
points = (Point[])point_arr.Clone();
}


public override double this[int i]
{
set
{
pointsIdea.y = value;
}
}
}

public static void Main()
{
Point[] point_arr = new PointMusic;

int i;

for (i = 0; i < 8; i++)
point_arrIdea = new Point();


point_arr[0].x = 0.0;
point_arr[0].y = 0.0;
point_arr[1].x = 1.0;
point_arr[1].y = 1.0;
point_arr[2].x = 2.0;
point_arr[2].y = 4.0;
point_arr[3].x = 3.0;
point_arr[3].y = 5.0;
point_arr[4].x = 4.0;
point_arr[4].y = 6.0;
point_arr[5].x = 5.0;
point_arr[5].y = 10.0;
point_arrDevil.x = 6.0;
point_arrDevil.y = 36.0;
point_arr[7].x = 7.0;
point_arr[7].y = 11.0;

AbstractClass ClsA = new ClassA(point_arr);
AbstractClass ClsB = new ClassB(point_arr);

ClsA[1] = 6; //This changes value in both objects!!!! I don't want that!!!


Visual C#17  
 
 
RizwanSharp





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

Arrays are reference types in C# so you are passing the same array in two objects, So when one changes it, the other reflects it and vice-versa.

The solution is to Create two different arrays and pass each to both objects. But problem will be still there.. What if main program changes the array It'll still be reflected in the objects...

So the Other Was is to Copy all the Elements of the Base Array to some other array and pass the secondary array to the function.

Here:

Point[] points1 = new Point[point_arr.Length];

Array.Copy([point_arr, points1, point1.Length);

Not pass the newly Created array to the constructor:

AbstractClass ClsA = new ClassA(points1);

I hope this will help.

Best Regards,

Rizwan



 
 
danni123





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

If I don't want to change main(), can I do something in object's constructor
Maybe somehow create another instance of this array

 
 
RizwanSharp





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

Sure, You can do the same in in the object itself which is taking the value and then creating a seperate copy and using it without chaning the main's data.....

But in this case you have to make sure one thing......

You pass the array to one object and it has started copying a seperate array, And while it is creating a copy some other object changes the base array........

So you have to manage these thing on your side...

I hope this makes the sense clearer.

Best Regards,

Rizwan



 
 
danni123





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

Still, I can't make it right.

I've changed my object's constructors:

class ClassA : AbstractClass
{
private Point[] points = new PointMusic;

public ClassA(Point[] point_arr)
{
Array.Copy(point_arr, points, points.Length);
}



But it's not working....

 
 
RizwanSharp





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

Ahhhhh, You are absolutely right, Array.Copy creates a Shallow copy, means it copies the references not the objects itself, You need to Deep Copy each object and then put them in the array again. A bit longer solution.

Here is some text from MSDN Magzine:

Passing and Returning Arrays
Arrays are always passed by reference to a method. Since the CLR doesn't support the notion of constant parameters, this means that the method is able to change the elements in the array. If you don't want to allow the method to modify the elements, then you must make a copy of the array and pass the copy into the method. Note that the Array.Copy method does a shallow copy, and therefore if the array's elements are reference types, the new array refers to the already existing objects.
To obtain a deep copy, you may want to clone the individual elements, but this requires that each object's type implements the ICloneable interface. Alternatively, you could serialize each object to a System.IO.MemoryStream and then immediately deserialize the memory stream to construct a new object. Depending on the object's types, the performance of these operations can be prohibitive and not all types are serializable either.
Similarly, some methods return a reference to an array. If the method constructs and initializes the array, then returning a reference to the array is fine. But if the method wants to return a reference to an internal array maintained by a field, then you must decide if you want the method's caller to have direct access to this array. If you do want it to have access, then just return the array's reference. Most often you do not, and the method should construct a new array and call Array.Copy, returning a reference to the new array. Again, you may want to clone each of the objects before returning the array reference.

See the Whole Article Here:

http://msdn.microsoft.com/msdnmag/issues/02/02/NET/

So the solution may be Serializing the each Point object to MemoryStream then construct all back again from the MemoryStream to create new objects and then put them in array.

This is a tricky solution but will surely work if you really want it in that way otherwaise you can go an easy way and create seperate copies of array to pass to multiple objects.

I hope this will help.

Best Regards,

Rizwan



 
 
danni123





PostPosted: Visual C# General, How to copy Array of objects, by values? Top

Wow! such a complex solution to a simple problem.
Thanks anyway.