equality

  • Thread starter Thread starter benben
  • Start date Start date
B

benben

I am a C++ guy recently migrated to C#. One of the thing I don't understand
is assignment (=) and equality (==) operators. If I try to do the following:

C a = new C;
C b = a;

Then I will get both a and b referring to the same object, which is not
exactly the copy constructor semantics in C++. But I can do the following to
remedy:

C c = new C(a);

But, what if I try to assign an object with another object? An assignment
operator only tries get the lvalue referring to the rvalue, so far I guess.

c = a; //now a, b and c are refering to the same object

Another situation I can get myself out is the use of equality operator (==).
So what does the semantic imply? Are they to answer "are the two references
referring to the same object?" or "are they equal by calling the overloaded
operator ==, if any?"

C d = new C;
C e = new C(d);
bool i = (d == e); //what do you say?

ben
 
benben said:
I am a C++ guy recently migrated to C#. One of the thing I don't understand
is assignment (=) and equality (==) operators. If I try to do the
following:

C a = new C;
C b = a;

Then I will get both a and b referring to the same object, which is not
exactly the copy constructor semantics in C++. But I can do the following
to
remedy:

C c = new C(a);
Right..it is not supposed to match copy constructor semantics however.
I would advise against trying to use copy constructors in .NET. They don't
work at all with interfaces and aren't particularly inuitive when it comes
to classes. What if C is actually a DerivedC implementation? A copy
constructor ends up breaking down the object chain. Note, .NET in general
and C# specifically don't define copy constructors and you shouldn't expect
*any* class to have one. If it does thats fine, but its far from guarenteed.
Many of the C(C val) type constructors you will see are actually using
containment or delegation and not copying.

There is a vauge pattern supported with the ICloneable interface, but it is
weak enough that there has been some discussion of obsoleting it.[1]

But, what if I try to assign an object with another object? An assignment
operator only tries get the lvalue referring to the rvalue, so far I
guess.

c = a; //now a, b and c are refering to the same object

Yes, this too is expected. Its actually pretty fundamental to the design of
the system. Note that this doesn't occur with value types (structs in C#),
only reference types.
Another situation I can get myself out is the use of equality operator
(==).
So what does the semantic imply? Are they to answer "are the two
references
referring to the same object?" or "are they equal by calling the
overloaded
operator ==, if any?"

C d = new C;
C e = new C(d);
bool i = (d == e); //what do you say?

It depends. if C overrides an equal operator, you may or may not get true.
If it doesn't, you will get false. Remember, since C# doesn't directly
understand copy constructors, there is no reason to assume that new C(d) is
a copy...it may be an aggregate or many other things.

Note, however, that overriden operators are based on variable type, so that

object d = new C();
object e = new C(d);
bool i = (d == e);
uses objects ==, which will result in i == false;

you can use Object.ReferenceEquals to verifiably compare references, but
otherwise you have no way of knowing how the comparison between two objects
is going to work outside of documentation telling you.

You might also want to read
http://blogs.msdn.com/csharpfaq/archive/2004/03/29/102224.aspx
1. http://blogs.msdn.com/brada/archive/2004/05/03/125427.aspx
 
Hashtable a = new Hashtable();
Hashtable b = new Hashtable();
a.Add("1","2");
b.Add("1","2");
System.Diagnostics.Debug.WriteLine(a==b);
....will return False.

ArrayList a = new ArrayList();
ArrayList b = new ArrayList();
a.Add("2");
b.Add("2");
System.Diagnostics.Debug.WriteLine(a==b);
....will return False.

string[] a = new string[]{"2","3"};
string[] b = new string[]{"2","3"};
string[] c = a;
System.Diagnostics.Debug.WriteLine(a==b);
System.Diagnostics.Debug.WriteLine(a==c);
....will return False, then True.

string a = "TEST";
string b = "TEST";
System.Diagnostics.Debug.WriteLine(a==b);
....will return True.

So my guess is that it will default to compare memory address of objects,
but use class operators if they exist.

Example:
public class Complex
{
private double real;
private double imag;

public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.Real+c2.Real, c1.Imag+c2.Imag);
}

public static Complex operator -(Complex c1, Complex c2)
{
return new Complex(c1.Real-c2.Real, c1.Imag-c2.Imag);
}
// ...
}
 
BenBen... I think the simplest explanation is that C++ classes use value
semantics by default and C# classes use reference semantics. (C#
structures
use value semantics.) This obviates the absolute need for a copy
constructor
in C# since you can have two references to the same object on the heap.
In
C# the object will only be collected when the object is unreachable so
you
don't need to worry about the "destructor" being called more than once
for a
given object on the heap. In other words, if you create two references
to a
single object, the destructor will only be called once, not twice. As a
result
there is no need to do a deep copy during assignment and no absolute
need
for a copy constructor in C#.

http://www.geocities.com/jeff_louie/OOP/oop5.htm

Regards,
Jeff
I am a C++ guy recently migrated to C#. One of the thing I don't
understand is assignment (=) and equality (==) operators. <
 
Why would you say if C is a derived class then a copy constructor will break
down the object chain? What is the "object chain" in the sense?

And with a class C which contains a defined C operator = (object o), what is
the semantic I will assume when interpreting the following assignments?

C a, b;
a = new C;
b = a;
C d = new C;
d = a;

I honestly do think with all these reference types C# could become an even
more ambiguous language than already ambiguous C++.

What if I have two references to object(s) which are of class in which
operator = () is defined and I try to test their identity? In C++ I can
always test againt their addresses, &a == &b. What is the equivalent
statement in C#?

Ben
benben said:
I am a C++ guy recently migrated to C#. One of the thing I don't understand
is assignment (=) and equality (==) operators. If I try to do the
following:

C a = new C;
C b = a;

Then I will get both a and b referring to the same object, which is not
exactly the copy constructor semantics in C++. But I can do the following
to
remedy:

C c = new C(a);
Right..it is not supposed to match copy constructor semantics however.
I would advise against trying to use copy constructors in .NET. They don't
work at all with interfaces and aren't particularly inuitive when it comes
to classes. What if C is actually a DerivedC implementation? A copy
constructor ends up breaking down the object chain. Note, .NET in general
and C# specifically don't define copy constructors and you shouldn't expect
*any* class to have one. If it does thats fine, but its far from guarenteed.
Many of the C(C val) type constructors you will see are actually using
containment or delegation and not copying.

There is a vauge pattern supported with the ICloneable interface, but it is
weak enough that there has been some discussion of obsoleting it.[1]

But, what if I try to assign an object with another object? An assignment
operator only tries get the lvalue referring to the rvalue, so far I
guess.

c = a; //now a, b and c are refering to the same object

Yes, this too is expected. Its actually pretty fundamental to the design of
the system. Note that this doesn't occur with value types (structs in C#),
only reference types.
Another situation I can get myself out is the use of equality operator
(==).
So what does the semantic imply? Are they to answer "are the two
references
referring to the same object?" or "are they equal by calling the
overloaded
operator ==, if any?"

C d = new C;
C e = new C(d);
bool i = (d == e); //what do you say?

It depends. if C overrides an equal operator, you may or may not get true.
If it doesn't, you will get false. Remember, since C# doesn't directly
understand copy constructors, there is no reason to assume that new C(d) is
a copy...it may be an aggregate or many other things.

Note, however, that overriden operators are based on variable type, so that

object d = new C();
object e = new C(d);
bool i = (d == e);
uses objects ==, which will result in i == false;

you can use Object.ReferenceEquals to verifiably compare references, but
otherwise you have no way of knowing how the comparison between two objects
is going to work outside of documentation telling you.

You might also want to read
http://blogs.msdn.com/csharpfaq/archive/2004/03/29/102224.aspx
1. http://blogs.msdn.com/brada/archive/2004/05/03/125427.aspx
 
benben said:
Why would you say if C is a derived class then a copy constructor will break
down the object chain? What is the "object chain" in the sense?

And with a class C which contains a defined C operator = (object o), what is
the semantic I will assume when interpreting the following assignments?

Not sure what you meant by the above, but you can't override the
assignment operator in C#.
C a, b;
a = new C;
b = a;
C d = new C;
d = a;

(Assuming changes of syntax from "new C;" to "new C();")

That creates two objects. One ends up being garbage almost immediately.
The final result is three variables all with the same value - namely a
reference to the object which was created first.
I honestly do think with all these reference types C# could become an even
more ambiguous language than already ambiguous C++.

Not at all - I don't see what's ambiguous about the above.
What if I have two references to object(s) which are of class in which
operator = () is defined and I try to test their identity?

I don't see how overriding the assignment operator is relevant. Do you
mean overriding the identity operator (==, not =)?
In C++ I can
always test againt their addresses, &a == &b. What is the equivalent
statement in C#?

Object.ReferenceEquals(a, b) will always test whether a and b are
references to the same object. Alternatively, a cast of either side to
object will force the "original" (as in for Object) meaning of == to be
used:

if ((object)a == b)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top