C # = operator problem

In C #, I have a simple three-dimensional vector class.

static void Main(string[] args) { Vector3D a, b; a = new Vector3D(0, 5, 10); b = new Vector3D(0, 0, 0); b = a; ax = 10; Console.WriteLine("vector a=" + a.ToString()); Console.WriteLine("vector b=" + b.ToString()); Console.ReadKey(); } 

output:

vector a = 10, 5, 10

vector b = 10, 5, 10

I assign a before changing ax to 10. So I was expecting

vector a = 10, 5, 10

vector b = 0, 5, 10

From what I understand = the operator assigns a reference to the object as a pointer? And in C # I can not overload = operator.

Do I need to manually assign each property?

+6
operators c #
source share
6 answers

Yes, because Vecor3D is a class, it is absolutely correct.

Classes are reference types, and the operator b = a; Does not copy an instance of Vector3D, but refers to an instance.

If you want to "clone" instances, you can add the IClonable interface, but this is more or less abandoned.

A better solution for type <X,Y,Z> might be to create a structure. Structures are value types, and the value b = a; will change (depending on what you want).

The three-dimensional point meets all the criteria for the structure (small, without identity). The preferred method is to create it as immutable.

+10
source share

Yes, "= the operator assigns a reference to the object as a pointer," as you put it. Thus, both a and b refer to the same single object in memory. (The object previously referenced b no longer referenced and garbage will be collected.)

There are several ways to overcome this problem:

  • Make Vector3D a struct instead of a class. Structures are value types instead of reference types, so b = a copies the contents of a to the variable b .

  • Inject the Clone method into your Vector3D class (previously this would mean implementing ICloneable , but this is no longer recommended ). Alternatively, you can create a Vector3D constructor that takes another vector as a parameter and creates a copy.

  • Manually copy the three values ​​yourself ( b = new Vector3D(ax, ay, az) ) if you cannot change the implementation of Vector3D .

+3
source share

Yes, reference types are disputed by reference.

If you want to have a separate instance, you want CLONE your instance.

Create a Vector3D.Clone () method that looks something like this:

 public Vector3D Clone() { return new Vector3D(this.x, this.y, this.x); } 

Then your main function should look like this:

 static void Main(string[] args) { Vector3D a, b; a = new Vector3D(0, 5, 10); b = new Vector3D(0, 0, 0); b = a.Clone(); ax = 10; Console.WriteLine("vector a=" + a.ToString()); Console.WriteLine("vector b=" + b.ToString()); Console.ReadKey(); } 

But as others have said, something smaller than Vector3D would be better suited as an immutable structure

+2
source share

You can change the Vector3D class to a structure. This will allow you to work with a value type instead of a reference type.

Another option is to implement ICloneable or use some other method to create a deep copy of your object.

+2
source share

You can make it a structure, as Henk says. And you can add a constructor

 struct Vector3D { public int x; public int y; public int z; public Vector3D(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public override string ToString() { return string.Format("{0}, {1}, {2}", x, y, z); } } 

You can also do this without adding a constructor.

 b = new Vector3D() {x=0, y=0, z=0}; 
+1
source share

No need to use struct , I suggest you create your Vector3D as an immutable class. Here are some good examples. Of course, ax = 10 not possible for an immutable class.

0
source share

All Articles