2

I am trying to copy a part of an array to a different location. Here is the declaration.

 public ObjectBasicFeatures[] ALLOBJECTS = new ObjectBasicFeatures[150];

When I do this,

ALLOBJECTS[1]= ALLOBJECTS[0];

Any changes made to either one cause a change in the other one.

From what I understand it is setting the pointers to the same address (Which is 'copying' it, but not what I want).

How can I copy the memory stored at pointer ALLOBJECTS[0] to ALLOBJECTS[1]?

Things tried:

  • Array.Copy() (Still copied the pointers...)
  • Using the dereference operator (Didn't work...)
pepperjack
  • 673
  • 6
  • 20
  • I think this is what you want https://msdn.microsoft.com/en-us/library/aa288474(v=vs.71).aspx – MistyK Feb 04 '17 at 17:57
  • 1
    if you really need to work with the concept of pointers in C#, there is a way with `unsafe` code. Otherwise, what you want is called deep copy or clone. Search for ICloneable, MemberwiseClone, Object.Clone. – Cee McSharpface Feb 04 '17 at 17:59
  • Possible duplicate of [How to make a deep copy of an array?](http://stackoverflow.com/questions/4054075/how-to-make-a-deep-copy-of-an-array) – jjj Feb 04 '17 at 18:00
  • @dlatikay which would be better for this exact situation, clone or deep copy? – pepperjack Feb 04 '17 at 18:00
  • I see no "exact situation"... what is in an `ObjectBasicFeatures` class? more info: http://stackoverflow.com/a/2200510/1132334 – Cee McSharpface Feb 04 '17 at 18:02
  • @dlatikay "exact situation," being simply copying 1 element of an array to another location. – pepperjack Feb 04 '17 at 18:05
  • sure, but unlike as in languages like C, where you could just copy the bytes and update the array with the pointer to the copy, it depends on the definition of the class (or struct) its members, if it is ICloneable or not, has a copy constructor or not. in the mean time there is already an answer that outlines one way of how to do it. – Cee McSharpface Feb 04 '17 at 18:08
  • @dlatikay C# and C/C++ behave essentially the same in relation to copy - copying objects as long as you consider proper equivalents - C# struct ~ C/C++ struct( + c++ class), C# class ~ c/C++ pointers. You'll get into the same problem using bitwise copy of c/c++ structs containing pointers as in C#, or exactly the same problem if array contains pointer. – Alexei Levenkov Feb 05 '17 at 05:35

3 Answers3

3

You need a copy constructor or make ObjectBasicFeatures a struct (struct is value type whereas class is a reference type) Then you could write:

ALLOBJECTS[1]= new ObjectBasicFeatures(ALLOBJECTS[0]);

Another Example:

class Program
{
    static void Main(string[] args)
    {
        var o1 = new ObjectBasicFeatures();
        var o2 = new ObjectBasicFeatures(o1);
        System.Diagnostics.Debug.Assert(!o1.Equals(o2));

    }
}

public class ObjectBasicFeatures
{
    public ObjectBasicFeatures()
    {
        MyProperty = 0;
    }

    /// <summary>
    /// copy constructor
    /// </summary>
    /// <param name="other"></param>
    public ObjectBasicFeatures(ObjectBasicFeatures other)
    {
        MyProperty = other.MyProperty;
    }

    public int MyProperty { get; set; }
}
Michał Zych
  • 149
  • 1
  • 8
1

To achieve this you need to create a constructor which takes input as its object and copies its values. But here is a catch. You need to do the same for all the classes you refer in ObjectBasicFeatures class and so on till the leaf node. Below is a piece of code I tested with.

Please no the value of member (direct member of class) does not reflect in other(copied) element but the value of level2.member is updated in both the objects when you change it in one object

class Program
{
    static void Main(string[] args)
    {
        ObjectBasicFeatures[] ALLOBJECTS = new ObjectBasicFeatures[3];
        ALLOBJECTS[0] = new ObjectBasicFeatures("zero");
        ALLOBJECTS[1] = new ObjectBasicFeatures("one");
        ALLOBJECTS[2] = new ObjectBasicFeatures("two");
        ALLOBJECTS[1] = new ObjectBasicFeatures(ALLOBJECTS[0]);
        ALLOBJECTS[0].member = "Updated Value";
        ALLOBJECTS[0].level2Member.member = "Updated Level 2 Value";
        Console.WriteLine("At index 0 : " + ALLOBJECTS[0].member + ", Level2 : " + ALLOBJECTS[0].level2Member.member);
        Console.WriteLine("At index 1 : " + ALLOBJECTS[1].member + ", Level2 : " + ALLOBJECTS[1].level2Member.member);
        Console.ReadKey();
    }
}

public class ObjectBasicFeatures
{
    public string member;
    public Level2 level2Member; // This is to demonstrate that it will be updated in both the objects
    public ObjectBasicFeatures(string memberVal)
    {
        member = memberVal;
        level2Member = new Level2("Level 2 Value");
    }

    /// Constructor to copy member values.
    public ObjectBasicFeatures(ObjectBasicFeatures originalObject)
    {
        member = originalObject.member;
        level2Member = originalObject.level2Member;
    }

}

/// This class does not have a constructor to copy member values.
public class Level2 
{
    public string member;
    public Level2(string memberVal)
    {
        member = memberVal;
    }
}

Output of this will look like below

enter image description here

Vineet Kumar
  • 176
  • 2
  • 11
0
ALLOBJECTS[1]= new ObjectBasicFeatures {
      PropertyName1=ALLOBJECTS[0].PropertyName1
      PropertyName2=ALLOBJECTS[0].PropertyName2

}

Hope this helps.

If your Class ObjectBasicFeatures has complex properties you should consider deep copy function

Greatran
  • 180
  • 3
  • 18