Skip to main content
GameDev.net gamedev.net
🔒 Locked

Reference object assignment by value.

Started by TheTroll Jul 28, 2007 at 1:43 PM 11 replies 10.2k views
Original Post
TheTroll
TheTroll
Ok, a strange question, for some reason I have never come across this before, so never had to figure out how to do it. Say I have the following.

public class MyClass
{
    public int Value;

    public MyClass(int value) {Value = value}
}

MyClass class1 = new MyClass(27);
MyClass class2 = new MyClass(84);

class1 = class2;  // now class1 and class2 both point to the same object so value = 84

class2.Value = 43;  // so now both are 43.


So what I want to do is assign by value instead of by reference so class1 gets the value of class2 but does not point to the same object. You might wonder why I am just not using structs. Well the classes I am uses inherit from a base class that has lots and lots of code in it that would have to be duplicated if I changed it to struct because you can't inherit. Any ideas, I just want to do class1 = class2 assignments because this is going to happen a lot and I don't want other people to get confused have to clone or copy it to get it to work right. theTroll
DarkTimes
DarkTimes
I know you don't want to use ICloneable, but in my mind it seems like the most obvious solution. Plus, although you say you want it so others can easy understand the code, but really anyone with a decent C# knowledge should know what Clone() does anyway. In fact I'd say class1 = class2.Clone(); conveys what's happening better than simply saying class1 = class2.

Edit: Dunno if this is strictly possible,but you could overload the = operator and do the cloning behind the scenes, but then that could cause issues for anyone expecting the default behaviour.
Telastyn
Telastyn
(From what I understand)


You don't. operator= is un-overridable and for classes it always does reference assign.

.Clone would work, a MyClass(MyClass rhs) constructor would work, a operator int(MyClass) ... lhs = 0 + rhs; is ugly but would work...

but no matter how you cut it, operator= for reference types always does reference assign.
TheTroll
TheTroll
I was hopping someone knew something I didn't know.

The problem is that I have a class that I really want to treat as a struct. I have a bunch of code in the base class, so it would be a pain maintenance wise to change it over to struct.

I have been trying to find a way around it, and just can't find one.

theTroll
Spoonbender
Spoonbender
Quote:
Original post by TheTroll
Any ideas, I just want to do class1 = class2 assignments because this is going to happen a lot and I don't want other people to get confused have to clone or copy it to get it to work right.


Well, doing as you want would definitely confuse people.
Anyone looking at your code will expect a class to use reference assignment, rather than a copy.

However, is it necessary for all the base class code to be in a base class? Could you in the struct simply keep a reference to an instance of the base class (which of course wouldn't then be a base class)
zz2
zz2
Quote:
Original post by Telastyn
(From what I understand)


You don't. operator= is un-overridable and for classes it always does reference assign.

.Clone would work, a MyClass(MyClass rhs) constructor would work, a operator int(MyClass) ... lhs = 0 + rhs; is ugly but would work...

but no matter how you cut it, operator= for reference types always does reference assign.


Something that is confusing me:
How is that a "string" (that is a class) returns a copy when using operator= and not a reference??!
Sneftel
Sneftel
It does return a reference. Not that it matters, because strings are immutable. There are no functions which change a string in-place, only functions which return a new string based on the old one.
zz2
zz2
It returns a reference of a new deep copy of a string. But how is that achieved? Could you post an example?
Telastyn
Telastyn
Quote:
Original post by zz2
It returns a reference of a new deep copy of a string. But how is that achieved? Could you post an example?


If I understand correctly, it doesn't return a new deep copy of a string. Just a reference. The trick comes when you try to modify that string. You can't because no methods exist to do so. The only thing you can do is make a new string with the modifications.
rip-off
rip-off
Quote:
Original post by zz2
It returns a reference of a new deep copy of a string. But how is that achieved? Could you post an example?


Nope.

It is reference assigment, but you cannot modify the original through the alias, as you cannot modify the String at all.
smitty1276
smitty1276
Two options...

class1 = class2.Clone();

or, my preferred method if it's just one value...

class1.value = class2.value;

Why are you "needing" to override the equals operator?
zz2
zz2
Quote:
Original post by Telastyn
If I understand correctly, it doesn't return a new deep copy of a string. Just a reference. The trick comes when you try to modify that string. You can't because no methods exist to do so. The only thing you can do is make a new string with the modifications.


aha I understand it now. Thanks
zz2
zz2
@TheTroll: I don't know if this can do any good but you could design your class to be immutable.
In your case:
public class MyClass{    private readonly int Value;    public MyClass(int value) {Value = value;}}MyClass class1 = new MyClass(27);MyClass class2 = new MyClass(84);class1 = class2;  // now class1 and class2 both point to the same object so value = 84class2.Value = 43;  // error - you cannot do thatclass2 = new MyClass(43);  //you have enforced this as an only way

PS: if you have a complex class and you decide to implement IClonable interface, you may save yourself some time (I think) if you use serialization in Clone method

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.