By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,957 Members | 1,234 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,957 IT Pros & Developers. It's quick & easy.

compare two structs via ==

P: n/a
I wish to compare two structs via == but it does not compile. I can
overload and create my own == but am I missing something that c#
already has implemented?

~titan

May 30 '07 #1
Share this Question
Share on Google+
50 Replies


P: n/a
No, you have not. If you overload ==, then you have to overload != as
well.

On top of that, you should also overload Equals and GetHashCode as well
to produce consistent results.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"titan nyquist" <ti***********@gmail.comwrote in message
news:11**********************@z28g2000prd.googlegr oups.com...
>I wish to compare two structs via == but it does not compile. I can
overload and create my own == but am I missing something that c#
already has implemented?

~titan

May 30 '07 #2

P: n/a
titan nyquist wrote:
I wish to compare two structs via == but it does not compile. I can
overload and create my own == but am I missing something that c#
already has implemented?
There is no default comparer for structs, as comparing the values as a
binary block of data doesn't always make sense.

If you for example have a struct:

public struct MyStruct {
private string _name;
public MyStruct(string name) { _name = name; }
public string Name { get { return _name; } }
}

If you then create two struct values that contains the same string value:

MyStruct v1 = new MyStruct("1");
MyStruct v2 = new MyStruct(1.ToString());

If you could compare these struct values as binary chunks of data, they
would not be equal, as the structs contains two different references,
eventhough the references points to string values that are equal.

--
Göran Andersson
_____
http://www.guffa.com
May 30 '07 #3

P: n/a
"Göran Andersson" <gu***@guffa.comha scritto nel messaggio
news:O7**************@TK2MSFTNGP06.phx.gbl...
>
There is no default comparer for structs, as comparing the values as a
binary block of data doesn't always make sense.
But why I can do this?

Point p1 = new Point(1, 2);

Point p2 = new Point(1, 2);

Console.WriteLine(p1 == p2);


May 31 '07 #4

P: n/a
"Fabio" <zn*******@virgilio.itschrieb im Newsbeitrag
news:uZ**************@TK2MSFTNGP04.phx.gbl...
"Göran Andersson" <gu***@guffa.comha scritto nel messaggio
news:O7**************@TK2MSFTNGP06.phx.gbl...
>>
There is no default comparer for structs, as comparing the values as a
binary block of data doesn't always make sense.

But why I can do this?

Point p1 = new Point(1, 2);

Point p2 = new Point(1, 2);

Console.WriteLine(p1 == p2);
Because an eqaulity operator is defined for Point in Point itself.

Christof
May 31 '07 #5

P: n/a
There is no *default* equality operator. Point declares one itself -
look in "reflector" to see it.

Marc
May 31 '07 #6

P: n/a
On May 31, 11:18 am, "Fabio" <znt.fa...@virgilio.itwrote:
There is no default comparer for structs, as comparing the values as a
binary block of data doesn't always make sense.

But why I can do this?

Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
Console.WriteLine(p1 == p2);
Because Point overloads the equality operator itself, along with
addition, subtraction etc.

Jon

May 31 '07 #7

P: n/a
On May 31, 11:32 am, "Jon Skeet [C# MVP]" <s...@pobox.comwrote:

<snip>

Oops. Looks like the automatic reply generator for myself, Marc and
Christof has got out of sync... Time to reboot ourselves again, guys.

(Anticipating some sort of equivalent reply from Marc and Christof
now...)

Jon

May 31 '07 #8

P: n/a
On May 31, 1:34 pm, "Jon Skeet [C# MVP]" <s...@pobox.comwrote:
On May 31, 11:32 am, "Jon Skeet [C# MVP]" <s...@pobox.comwrote:

<snip>

Oops. Looks like the automatic reply generator for myself, Marc and
Christof has got out of sync... Time to reboot ourselves again, guys.

(Anticipating some sort of equivalent reply from Marc and Christof
now...)

Jon
Hi,

This proves what the *asynchronous* fellows mentioned =)

[Serializable, StructLayout(LayoutKind.Sequential),
TypeConverter(typeof(PointConverter)), ComVisible(true)]
public struct Point
{
...
public static bool operator ==(Point left, Point right);
public static bool operator !=(Point left, Point right);
...
}

Moty

May 31 '07 #9

P: n/a
It'd be nice if C# generated a default memberwise equality operator, but I
suppose there's a good reason why it doesn't.

///ark
Jun 1 '07 #10

P: n/a
Mark Wilden wrote:
It'd be nice if C# generated a default memberwise equality operator, but I
suppose there's a good reason why it doesn't.
Yes, there is.

Did you miss my post explaining that a memberwise comparision dosen't
always make sense?

--
Göran Andersson
_____
http://www.guffa.com
Jun 1 '07 #11

P: n/a
"Göran Andersson" <gu***@guffa.comwrote in message
news:ex**************@TK2MSFTNGP02.phx.gbl...
Did you miss my post explaining that a memberwise comparision dosen't
always make sense?
I saw the post from you talking about a bitwise comparison, but not a
memberwise comparison. In the latter, you'd compare each member, using its
== operator.

Did I miss a post?

///ark
Jun 1 '07 #12

P: n/a
Mark Wilden wrote:
"Göran Andersson" <gu***@guffa.comwrote in message
news:ex**************@TK2MSFTNGP02.phx.gbl...
>Did you miss my post explaining that a memberwise comparision dosen't
always make sense?

I saw the post from you talking about a bitwise comparison, but not a
memberwise comparison. In the latter, you'd compare each member, using its
== operator.

Did I miss a post?

///ark
Ok, I misunderstood your distinction there. Anyway, not even a
memberwise comparison would always make sense.

--
Göran Andersson
_____
http://www.guffa.com
Jun 2 '07 #13

P: n/a
Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's members
(using the same criterion for member equality).

Jun 4 '07 #14

P: n/a
Mark Wilden wrote:
Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's members
(using the same criterion for member equality).
Usually, but not always.

I have a faint memory of reading somewhere that the decision to not
include an automatic memberwise comparison for structs was that it would
automatically add functionality to all structs that you create. If the
comparison doesn't make sense for a struct, you would be forced to
override it even if it didn't make sense to compare the structs at all.
It would not be possible to prevent usage of the comparison at compile
time, it could only throw an exception at run time.

If you want a memberwise comparison for a struct, it's very easy to
write one, and you can most likely make it more efficient than any
automatically generated code, as you can choose the order to compare the
fields so that you first compare the fields that is most likely to differ.

--
Göran Andersson
_____
http://www.guffa.com
Jun 5 '07 #15

P: n/a
On Jun 5, 12:06 pm, Göran Andersson <g...@guffa.comwrote:

<snip>
If you want a memberwise comparison for a struct, it's very easy to
write one, and you can most likely make it more efficient than any
automatically generated code, as you can choose the order to compare the
fields so that you first compare the fields that is most likely to differ.
It's also worth bearing in mind that although the equality operators
aren't generated for you, ValueType.Equals does a memberwise
comparison, using a fast bit comparison where appropriate and calling
Equals on each field otherwise. It's not fast, but it works.

In other words, if you don't care about performance then implementing
== and != can be as simple as calling Equals.

(While I'm on the topic of == and !=, can anyone think of any reason
why you'd ever implement them to return a type other than bool? I
wasn't even aware it could be done until a few days ago.)

Jon

Jun 5 '07 #16

P: n/a
Oh dear... any readers of The Daily WTF (as was) will know that this
is so that you can return...

public enum TriBool {True, False, FileNotFound}

;-p
Jun 5 '07 #17

P: n/a
More sensibly... news to me too; I've just tested it, and you are
absolutely correct (which I fully expected, but sometimes you just
have to see these things for yourself).

Perhaps it realtes to lifted operators and null propegation for
Nullable<T(334: 8.19)??

Marc
Jun 5 '07 #18

P: n/a
Ignore the lifted operator comment - reading more closely, comparison
operators are lifted in the arguments only (not the result).

There is also the unary true / false operator... but I'm still none
the wiser. Interesting.

Marc
Jun 5 '07 #19

P: n/a
On Jun 5, 12:43 pm, "Marc Gravell" <marc.grav...@gmail.comwrote:
More sensibly... news to me too; I've just tested it, and you are
absolutely correct (which I fully expected, but sometimes you just
have to see these things for yourself).

Perhaps it realtes to lifted operators and null propegation for
Nullable<T(334: 8.19)??
Nope - because the lifted operators for equality *only* work when the
return type is bool, and the lifted form is still bool.

And yes, I know this from memory because I've just been writing about
it - it's
the only way I found out about the oddity to start with :)

Jon

Jun 5 '07 #20

P: n/a
Jon Skeet [C# MVP] wrote:
On Jun 5, 12:06 pm, Göran Andersson <g...@guffa.comwrote:

<snip>
>If you want a memberwise comparison for a struct, it's very easy to
write one, and you can most likely make it more efficient than any
automatically generated code, as you can choose the order to compare the
fields so that you first compare the fields that is most likely to differ.

It's also worth bearing in mind that although the equality operators
aren't generated for you, ValueType.Equals does a memberwise
comparison, using a fast bit comparison where appropriate and calling
Equals on each field otherwise. It's not fast, but it works.

In other words, if you don't care about performance then implementing
== and != can be as simple as calling Equals.

(While I'm on the topic of == and !=, can anyone think of any reason
why you'd ever implement them to return a type other than bool? I
wasn't even aware it could be done until a few days ago.)

Jon
I have create a Data access layer, something like DLinq.
I created a class Expression where operator== yields a new compound
expression:

public static Expression operator==(Expression a, Expression b)
{
return GenerateBinaryExpression("=", a, b);
}

So the syntax allows calls like that:

ProjektstundenTable ps = Tables.Projektstunden;
SelectQuery query = new SelectQuery();
query.From(ps);
query.Select(query.Functions.Sum(ps.fpStunden));

// note that this ==, not beeing a string is NOT evaluated in code
// but instead, it is internally converted to an expression string and
// sent to the database!
query.Where(ps.ProjektRessourcenID==this.ID);
Jun 5 '07 #21

P: n/a
Jon Skeet [C# MVP] wrote:
(While I'm on the topic of == and !=, can anyone think of any reason
why you'd ever implement them to return a type other than bool? I
wasn't even aware it could be done until a few days ago.)
Fuzzy logic? Return a float value between 0 and 1...

--
Göran Andersson
_____
http://www.guffa.com
Jun 5 '07 #22

P: n/a
On Jun 5, 1:07 pm, cody <deutron...@gmx.dewrote:
I have create a Data access layer, something like DLinq.
I created a class Expression where operator== yields a new compound
expression:

public static Expression operator==(Expression a, Expression b)
{
return GenerateBinaryExpression("=", a, b);
}
Hmm. I can sort of see the benefit, but at the same time it feels
sufficiently unlike the *normal* meaning of == that I'd be loathe to
do something like that myself.

Jon

Jun 5 '07 #23

P: n/a
On Jun 5, 1:09 pm, Göran Andersson <g...@guffa.comwrote:
(While I'm on the topic of == and !=, can anyone think of any reason
why you'd ever implement them to return a type other than bool? I
wasn't even aware it could be done until a few days ago.)

Fuzzy logic? Return a float value between 0 and 1...
I guess my problem with things like that is that it would be such non-
idiomatic C# at that point that I'd rather have a method to explain
what's going on. I guess it just shows that C# wasn't designed
entirely according to my personal preferences :)

Jon

Jun 5 '07 #24

P: n/a
Jon Skeet [C# MVP] wrote:
On Jun 5, 1:09 pm, Göran Andersson <g...@guffa.comwrote:
>>(While I'm on the topic of == and !=, can anyone think of any reason
why you'd ever implement them to return a type other than bool? I
wasn't even aware it could be done until a few days ago.)
Fuzzy logic? Return a float value between 0 and 1...

I guess my problem with things like that is that it would be such non-
idiomatic C# at that point that I'd rather have a method to explain
what's going on. I guess it just shows that C# wasn't designed
entirely according to my personal preferences :)
Or perhaps it proves that just because you _can_ do something, it might
not be the best idea to do it. :)
Another reason for this that I can think of is the "no" reason. :)

When designing the language, they might simply have found no compelling
reason to limit the == operator to return a bool.

--
Göran Andersson
_____
http://www.guffa.com
Jun 5 '07 #25

P: n/a
On Jun 5, 3:59 pm, Göran Andersson <g...@guffa.comwrote:
I guess my problem with things like that is that it would be such non-
idiomatic C# at that point that I'd rather have a method to explain
what's going on. I guess it just shows that C# wasn't designed
entirely according to my personal preferences :)

Or perhaps it proves that just because you _can_ do something, it might
not be the best idea to do it. :)
Indeed (like relying on the order of initializer execution, to pick an
example from another thread).
Another reason for this that I can think of is the "no" reason. :)

When designing the language, they might simply have found no compelling
reason to limit the == operator to return a bool.
True. Just looking at the language spec, it's at least discouraged:

<quote>
Although it is possible for a user-defined operator to perform any
computation it pleases, implementations that produce results other
than those that are intuitively expected are strongly discouraged. For
example, an implementation of operator== should compare the two
operands for equality and return an appropriate bool result.
</quote>

Jon

Jun 5 '07 #26

P: n/a
"Göran Andersson" <gu***@guffa.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's members
(using the same criterion for member equality).

Usually, but not always.
No - always. That was the definition of equality.

Your other comments indicate that the decision didn't have anything to do
with C# in particular, but language design as a whole. Interesting.

///ark
Jun 5 '07 #27

P: n/a
On Tue, 05 Jun 2007 13:43:09 -0700, Mark Wilden <mw*****@communitymtm.com
wrote:
>>Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's
members (using the same criterion for member equality).

Usually, but not always.

No - always. That was the definition of equality.
As long as the = operator wasn't overloaded, you mean.

Pete
Jun 5 '07 #28

P: n/a
Mark Wilden wrote:
"Göran Andersson" <gu***@guffa.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>>Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's members
(using the same criterion for member equality).
Usually, but not always.

No - always. That was the definition of equality.
Ok, but then the definition of equality didn't always make sense.

--
Göran Andersson
_____
http://www.guffa.com
Jun 6 '07 #29

P: n/a
"Göran Andersson" <gu***@guffa.comwrote in message
news:eI**************@TK2MSFTNGP06.phx.gbl...
Mark Wilden wrote:
>"Göran Andersson" <gu***@guffa.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>>>Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's
members (using the same criterion for member equality).

Usually, but not always.

No - always. That was the definition of equality.

Ok, but then the definition of equality didn't always make sense.
Do you have an example? Like I said, it seemed to work well for us.

///ark
Jun 6 '07 #30

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Tue, 05 Jun 2007 13:43:09 -0700, Mark Wilden <mw*****@communitymtm.com>
wrote:
>>Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's
members (using the same criterion for member equality).

Usually, but not always.

No - always. That was the definition of equality.
As long as the == operator wasn't overloaded, you mean.
We're not talking about overloading ==, since that would imply comparing an
object to a different kind of object. We're talking about comparing an
object to an object of the same class - no overloading.

The behavior of operator== could be overridden, but that I would maintain
that that didn't change the definition of object equality. Someone could
overload == to format your hard drive, but that doesn't change C++'s
definition of equality, which is that two objects are equal iff. all their
members are equal.

But if someone's idea of equality was different from the language's, then
you're right - they could certainly use == to implement that idea. And that
was sometimes done, of course, for legitimate reasons.

It's hard for me to imagine, however, that two objects whose members were
equal to each other would not be equal... But I could be wrong.

And of course "equal" is not the same thing as "identical."

///ark
Jun 6 '07 #31

P: n/a
On Wed, 06 Jun 2007 16:08:47 -0700, Mark Wilden <mw*****@communitymtm.com
wrote:
We're not talking about overloading ==, since that would imply comparing
an
object to a different kind of object.
Why would it imply that?

Overloading the == operator is perfectly fine for the purpose of modifying
the default memberwise-compare behavior. For example, when you want two
instances to compare as equal as long as they contain strings that are
identical, even if the strings themselves are different instances.
We're talking about comparing an
object to an object of the same class - no overloading.
I don't see why comparing an object to an object of the same class implies
no overloading.
The behavior of operator== could be overridden, but that I would maintain
that that didn't change the definition of object equality. Someone could
overload == to format your hard drive, but that doesn't change C++'s
definition of equality, which is that two objects are equal iff. all
their
members are equal.
I disagree that that's the only valid definition of equality in C++.
Specifically because of operator overloading.
But if someone's idea of equality was different from the language's, then
you're right - they could certainly use == to implement that idea.And
that
was sometimes done, of course, for legitimate reasons.

It's hard for me to imagine, however, that two objects whose members were
equal to each other would not be equal... But I could be wrong.
In C# that happens all the time. By default if you compare two
references, then even if the members are equal to each other, if the
actual references are not equal the objects are not equal.
And of course "equal" is not the same thing as "identical."
Well, that's my point. "equal" is whatever it has been defined to be ina
particular context. Because of operator overloading, this varies. There
is no one "equals" that is defined.

Pete
Jun 7 '07 #32

P: n/a
Mark Wilden wrote:
It's hard for me to imagine, however, that two objects whose members were
equal to each other would not be equal... But I could be wrong.
It's the inequality that is the problem. Just because some of the fields
in two objects are not equal doesn't mean that the obejcts are not
equal. One field in an object may determine if another field should be
included or not when deciding equality.

And also of course if you define two separate instances to be unequal,
as Peter mentioned.

--
Göran Andersson
_____
http://www.guffa.com
Jun 7 '07 #33

P: n/a
Mark Wilden wrote:
"Göran Andersson" <gu***@guffa.comwrote in message
news:eI**************@TK2MSFTNGP06.phx.gbl...
>Mark Wilden wrote:
>>"Göran Andersson" <gu***@guffa.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl.. .

Memberwise comparison worked pretty well in C++. An object is equal to
another object if all its members are equal to the other object's
members (using the same criterion for member equality).
>
Usually, but not always.
No - always. That was the definition of equality.
Ok, but then the definition of equality didn't always make sense.

Do you have an example? Like I said, it seemed to work well for us.

///ark
Easily:

public struct ValidDouble {
private bool _valid;
private double _value;
...
}

If two values have _valid set to false, you might want to consider them
equal, regardless of the value of _value;

--
Göran Andersson
_____
http://www.guffa.com
Jun 7 '07 #34

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Wed, 06 Jun 2007 16:08:47 -0700, Mark Wilden <mw*****@communitymtm.com>
wrote:
>We're not talking about overloading ==, since that would imply comparing
an object to a different kind of object.
Why would it imply that?
Overloading means adding another method with the same name but a different
signature. It's easy to confuse overloading with overriding, as my own post
proved. :)

The non-overloaded operator== that C++ automatically generates takes as its
argument a member of the same class or a base class of the same class
(IIRC). Overloading means to leave that method alone and add another method
that takes, for example, an int as the argument. I believe you're talking
about overriding, where a child class overrides a parent class method (with
the same signature) to do something different than the parent.
>Overloading the == operator is perfectly fine for the purpose of modifying
the default memberwise-compare behavior. For example, when you want two
instances to compare as equal as long as they contain strings that are
identical, even if the strings themselves are different instances.
Actually, that would be encompassed by a plain ol' memberwise compare.
Strings with identical contents are indeed equal. To just compare the
addresses would be the old bitwise comparison.
>In C# that happens all the time. By default if you compare two
references, then even if the members are equal to each other, if the
actual references are not equal the objects are not equal.
I think that would be confusing, since equality is different from
identicality (?).
>And of course "equal" is not the same thing as "identical."
Well, that's my point. "equal" is whatever it has been defined to be in a
particular context. Because of operator overloading, this varies. There
is no one "equals" that is defined.
"Equals" has indeed been defined in C++ as I explained. This is proven by
the fact that it used to be different in earlier versions of the language.
You're right that one can change the behavior of an operator with two sets
of two lines to mean anything one wants (including global thermonuclear
war). But I maintain that the language itself is clear on the concept.

But this is a semantic difference. I think we each know what the other is
talking about (pace the overloading/overriding business).

///ark
Jun 7 '07 #35

P: n/a
"Göran Andersson" <gu***@guffa.comwrote in message
news:O8**************@TK2MSFTNGP03.phx.gbl...
>
public struct ValidDouble {
private bool _valid;
private double _value;
...
}

If two values have _valid set to false, you might want to consider them
equal, regardless of the value of _value;
Good example. I stand corrected.

So I'll restate :). Memberwise comparison makes sense in the vast majority
of structures and classes that I've defined or seen defined.

///ark
Jun 7 '07 #36

P: n/a
On Thu, 07 Jun 2007 10:41:17 -0700, Mark Wilden <mw*****@communitymtm.com
wrote:
Overloading means adding another method with the same name but a
different
signature. It's easy to confuse overloading with overriding, as my own
post
proved. :)
I get your gist, but for better or worse (you may argue "worse" :) ),
redefining the behavior of an operator in C++ (and I think C# too) is
always called "overloading". That's why, for example, there are document
pages for "Operator Overloading" but none for "Operator Overriding".
The non-overloaded operator== that C++ automatically generates takes as
its
argument a member of the same class or a base class of the same class
(IIRC). Overloading means to leave that method alone and add another
method
that takes, for example, an int as the argument. I believe you're talking
about overriding, where a child class overrides a parent class method
(with
the same signature) to do something different than the parent.
How is the syntax for what you call an "operator override" different from
the syntax described in the documentation for "Operator Overloading"
(http://msdn2.microsoft.com/en-us/library/5tk49fh2.aspx, for example)?
And why does the C# documentation use the terms "override" and "overload"
interchangeably in this page:
http://msdn2.microsoft.com/en-us/library/ms173147.aspx

Again, I understand where you're coming from, but the real world does not
use such black & white distinctions between "overload" and "override", and
so if that's the only complaint you've got about my comment about
overloading the == operator, I think you're making too much hay overit.
>Overloading the == operator is perfectly fine for the purpose of
modifying
the default memberwise-compare behavior. For example, when you want two
instances to compare as equal as long as they contain strings that are
identical, even if the strings themselves are different instances.

Actually, that would be encompassed by a plain ol' memberwise compare.
Strings with identical contents are indeed equal. To just compare the
addresses would be the old bitwise comparison.
Actually, it would not. I'm talking about a class that contains
*references* to strings, and a member-wise compare will not detect the
equality case when the strings contain identical data but are different
references.
>In C# that happens all the time. By default if you compare two
references, then even if the members are equal to each other, if the
actual references are not equal the objects are not equal.

I think that would be confusing, since equality is different from
identicality (?).
I'm not sure what you mean here. You wrote "It's hard for me to imagine,
however, that two objects whose members were
equal to each other would not be equal... But I could be wrong." I
replied by pointing out that with the default reference-equality behavior,
even when members are the same, the objects are not equal.

Whether you think it would be confusing isn't relevant as far as I can
tell. The fact is, that's how it works. I gave an example of a situation
in which two objects are considered not equal even though they have
members that are equal.
"Equals" has indeed been defined in C++ as I explained.
And as I explained, what's "equal" depends on how you've defined the ==
operator. It's not an absolute.

Pete
Jun 7 '07 #37

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:

<snip>
And why does the C# documentation use the terms "override" and "overload"
interchangeably in this page:
http://msdn2.microsoft.com/en-us/library/ms173147.aspx
It doesn't - you *override* the single method signature

bool Equals(object other)

but you *overload* the == operator by providing different signatures,
eg
bool operator ==(string x, string y)
bool operator ==(DateTime x, DateTime y)

Is there anything in the article which goes against that? I could see
anything in a brief skim, but I'm happy to look at any particular bits
more closely.
Again, I understand where you're coming from, but the real world does not
use such black & white distinctions between "overload" and "override", and
so if that's the only complaint you've got about my comment about
overloading the == operator, I think you're making too much hay over it.
I haven't been following the conversation closely enough, but overload
and override are pretty well defined in the C# and .NET world.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jun 7 '07 #38

P: n/a
On Thu, 07 Jun 2007 11:37:47 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
but you *overload* the == operator by providing different signatures,
eg
bool operator ==(string x, string y)
bool operator ==(DateTime x, DateTime y)
You seem to be in agreement with me. Mark's claim was that it's only
"overloading" when the types are different. However, both of your
examples show using the == operator on identical types. This is theway
I'm using the phrase "overload" as well.
Is there anything in the article which goes against that? I could see
anything in a brief skim, but I'm happy to look at any particular bits
more closely.
Look at the text in the section named "Overriding Operator ==":

By default, the operator == tests for reference equality by determining
if two references indicate the same object, so reference types do not
need to implement operator == in order to gain this functionality. When
a type is immutable, meaning the data contained in the instance cannot
be
changed, overloading operator == to compare value equality instead of
reference equality can be useful because, as immutable objects, they
can
be considered the same as long as they have the same value. Overriding
operator == in non-immutable types is not recommended.

Overloaded operator == implementations should not throw exceptions. Any
type that overloads operator == should also overload operator !=. For
example:

I do not read that text as talking about anything other than changing the
behavior of the == operator in a specific case. But within two
paragraphs, the word "override" is used only once (twice, if you count the
heading), while the word "overload" is used four times. As near as I can
tell, the words are used interchangeably.
I haven't been following the conversation closely enough, but overload
and override are pretty well defined in the C# and .NET world.
I certainly understand the distinction (even if I've confused the two on
occasion in the past :) ). However, I have only ever called the act of
changing an operator's beahvior "overloading", even when I haven't changed
the types involved in the comparison. Nor have I ever seen documentation
that makes a clear distinction between the two in that case. Even in the
context of C#, where the two terms are clearly distinct as applied to
methods, when talking about operators, the same care is not taken to
distinguish the two.

Pete
Jun 7 '07 #39

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
On Thu, 07 Jun 2007 11:37:47 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
but you *overload* the == operator by providing different signatures,
eg
bool operator ==(string x, string y)
bool operator ==(DateTime x, DateTime y)

You seem to be in agreement with me. Mark's claim was that it's only
"overloading" when the types are different. However, both of your
examples show using the == operator on identical types. This is the way
I'm using the phrase "overload" as well.
It's not that the types are different to each other within the
signature - it's that the *signatures* are different.

Basically, if the string type didn't overload the == operator with

bool operator ==(string x, string y)

then there wouldn't be any such operator. There's be the implicit

bool operator ==(object x, object y)

but that's got a different signature, so isn't overridden by the string
one. (And wouldn't be anyway, as they're always static... which I
realise I haven't included above.)
Is there anything in the article which goes against that? I could see
anything in a brief skim, but I'm happy to look at any particular bits
more closely.

Look at the text in the section named "Overriding Operator ==":

By default, the operator == tests for reference equality by determining
if two references indicate the same object, so reference types do not
need to implement operator == in order to gain this functionality. When
a type is immutable, meaning the data contained in the instance cannot
be
changed, overloading operator == to compare value equality instead of
reference equality can be useful because, as immutable objects, they
can
be considered the same as long as they have the same value. Overriding
operator == in non-immutable types is not recommended.

Overloaded operator == implementations should not throw exceptions. Any
type that overloads operator == should also overload operator !=. For
example:

I do not read that text as talking about anything other than changing the
behavior of the == operator in a specific case. But within two
paragraphs, the word "override" is used only once (twice, if you count the
heading), while the word "overload" is used four times. As near as I can
tell, the words are used interchangeably.
"Overriding" there is a mistake. As operators are implemented as static
methods, they can't be overridden. Apologies for not finding it before
- I looked for "override" which of course misses "overriding".
I haven't been following the conversation closely enough, but overload
and override are pretty well defined in the C# and .NET world.

I certainly understand the distinction (even if I've confused the two on
occasion in the past :) ). However, I have only ever called the act of
changing an operator's beahvior "overloading", even when I haven't changed
the types involved in the comparison. Nor have I ever seen documentation
that makes a clear distinction between the two in that case.
There's no such thing as operator overriding, basically - could you
given an example where you think you *have* been doing what you'd call
operator overriding?
Even in the
context of C#, where the two terms are clearly distinct as applied to
methods, when talking about operators, the same care is not taken to
distinguish the two.
It is by some - just not by all :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jun 7 '07 #40

P: n/a
On Thu, 07 Jun 2007 12:46:19 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
[...]
There's no such thing as operator overriding, basically - could you
given an example where you think you *have* been doing what you'd call
operator overriding?
Nope. As I mentioned, *I* always call it "overloading" (whether I do so
knowing the intricacies of the difference between the two is a separate
question :) ).

It's Mark who wrote "We're not talking about overloading ==, since that
would imply comparing an object to a different kind of object. We're
talking about comparing an object to an object of the same class - no
overloading." and "The behavior of operator== could be overridden"

Maybe he could offer such an example. :)

Pete
Jun 7 '07 #41

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
[...]
There's no such thing as operator overriding, basically - could you
given an example where you think you *have* been doing what you'd call
operator overriding?

Nope. As I mentioned, *I* always call it "overloading" (whether I do so
knowing the intricacies of the difference between the two is a separate
question :) ).

It's Mark who wrote "We're not talking about overloading ==, since that
would imply comparing an object to a different kind of object. We're
talking about comparing an object to an object of the same class - no
overloading." and "The behavior of operator== could be overridden"

Maybe he could offer such an example. :)
And definitely talking about C# at the time? If so, I agree, that's
wrong.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jun 7 '07 #42

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Thu, 07 Jun 2007 10:41:17 -0700, Mark Wilden <mw*****@communitymtm.com>
wrote:
>How is the syntax for what you call an "operator override" different from
the syntax described in the documentation for "Operator Overloading"
(http://msdn2.microsoft.com/en-us/library/5tk49fh2.aspx, for example)?

That page uses the term as I understand it. "This gives the operator more
than one meaning, or 'overloads' it." Overriding, on the other hand,
replaces the -one- meaning the operator used to have.
>And why does the C# documentation use the terms "override" and "overload"
interchangeably in this page:
http://msdn2.microsoft.com/en-us/library/ms173147.aspx

Sloppiness. :)
>Actually, it would not. I'm talking about a class that contains
*references* to strings, and a member-wise compare will not detect the
equality case when the strings contain identical data but are different
references.

Operator == for string references compares the strings' contents.

///ark
Jun 7 '07 #43

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Is there anything in the article which goes against that? I could see
anything in a brief skim, but I'm happy to look at any particular bits
more closely.
Near the end, they talk about adding a method to the ThreeDPoint class,
operator==(ThreeDPoint a, ThreeDPoint b) and they use both "overloading" and
"overriding" to describe it.

///ark
Jun 7 '07 #44

P: n/a
On Thu, 07 Jun 2007 13:23:46 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
And definitely talking about C# at the time? If so, I agree, that's
wrong.
At this point, I would be loathe to say for sure that he was "talking
about C# at the time". This thread is a result of discussing both C++ and
C# equality operations, and I think it was pretty clear that his original
statement to which I responded was specifically about C++ and not C#.
However, I can't comment on the more general use of his attempt to
describe the differences between "overload" and "override". I suppose he
might feel that they are used differently in C++ than in C#.

Rather than put words into his mouth, I will let Mark clarify if necessary.

Pete
Jun 7 '07 #45

P: n/a
On Thu, 07 Jun 2007 13:28:19 -0700, Mark Wilden <mw*****@communitymtm.com
wrote:
>Actually, it would not. I'm talking about a class that contains
*references* to strings, and a member-wise compare will not detect the
equality case when the strings contain identical data but are different
references.

Operator == for string references compares the strings' contents.
And? I'm not talking about operator==(string, string). I'm talkingabout
operator==(myclass, myclass) where the class "myclass" has members that
are references to strings.

Pete
Jun 7 '07 #46

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
>It's Mark who wrote "We're not talking about overloading ==, since that
would imply comparing an object to a different kind of object. We're
talking about comparing an object to an object of the same class - no
overloading." and "The behavior of operator== could be overridden"
Yup, I forgot that in C# (as opposed to C++, which was the original subject
of my post), operators are always static.

Nevertheless, the distinction between the terms "overload" and "override" is
well-understood in the C++ world - even by me (I think). Just consider the
English meaning of the terms. Overriding implies that the original behavior
is gone - it is overridden, like the override switch for autopilot.
Overloading means that the method name has been "loaded" with another
meaning - the original behavior is still there. Think of a burro.

///ark
Jun 7 '07 #47

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
I think it was pretty clear that his original statement to which I
responded was specifically about C++ and not C#.
You are correct. I was talking about how the default for memberwise
comparison in C++ worked well enough that I didn't know why C# didn't use
it.
However, I can't comment on the more general use of his attempt to
describe the differences between "overload" and "override". I suppose he
might feel that they are used differently in C++ than in C#.
No, each term has the same meaning in both languages (as well as English).
Jun 7 '07 #48

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
>And? I'm not talking about operator==(string, string). I'm talking about
operator==(myclass, myclass) where the class "myclass" has members that
are references to strings.
Right. And a memberwise comparison would report those two objects (of
myclass) to be equal. No need to overload/override.

///ark
Jun 7 '07 #49

P: n/a
On Thu, 07 Jun 2007 13:45:56 -0700, Mark Wilden <mw*****@communitymtm.com
wrote:
>And? I'm not talking about operator==(string, string). I'm talking
about
operator==(myclass, myclass) where the class "myclass" has members that
are references to strings.

Right. And a memberwise comparison would report those two objects (of
myclass) to be equal. No need to overload/override.
Well, I should clarify it appears. When I write "string", I'm assuming
the old, pre-.NET days when my strings were all actually char arrays. I
can't speak to the use of the actual "String" class in managed C++, but
the old C++ behavior certainly did not pick up on references to strings
that are different, but which contained the same characters.

Without an operator== overload that would explicitly check equality on the
string arrays, the class instances would be "not equal" even though the
members are "equal".

Again, it all depends on how you're defining "equality". In any case,
even if you insist on defining "equal" to invalidate the example I offer,
the fact remains that in C++, the "definition" of equality depends on how
the operator == has been overloaded. Which is, as it happens, my original
point.

Interesting how a single sentence could digress into such a convoluted
discussion.

Pete
Jun 7 '07 #50

50 Replies

This discussion thread is closed

Replies have been disabled for this discussion.