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

Why cast to Object to compare strings?

P: n/a

Why would you cast two strings to objects to compare them? I saw code
in an MS sample on MSDN and don't get it.

if ( (object)name == (object)attr.name ) {

both "name" and "attr.name" are declared as string.

http://msdn.microsoft.com/XML/Buildi...mlBkMkRead.asp

Thanks,

Sam
B-Line is now hiring one Washington D.C. area VB.NET
developer for WinForms + WebServices position.
Seaking mid to senior level developer. For
information or to apply e-mail resume to
sam_blinex_com.
Nov 17 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a

"Samuel R. Neff" <bl****@newsgroup.nospam> wrote in message
news:ia********************************@4ax.com...

Why would you cast two strings to objects to compare them? I saw code
in an MS sample on MSDN and don't get it.

if ( (object)name == (object)attr.name ) {

both "name" and "attr.name" are declared as string.

It is to circumvent operator overloading. By casting to object here, you
force the compiler to use objects == operator, which is a reference
comparison, whereas not casting would have used strings == operator, which
is a string comparison(full character to character compare). I don't know
specifically why the author felt reference comparison was important here(I
can't find it in your example), but that is the effect.

I personally prefer to use object.ReferenceEquals() instead of casting the
two instances to object. http://msdn.microsoft.com/XML/Buildi...mlBkMkRead.asp

Thanks,

Sam
B-Line is now hiring one Washington D.C. area VB.NET
developer for WinForms + WebServices position.
Seaking mid to senior level developer. For
information or to apply e-mail resume to
sam_blinex_com.

Nov 17 '05 #2

P: n/a

Thanks, I didn't realize casting affected operator overload
resolution.

Wish I knew why the writer wanted to use reference comparison for
strings though, it's weird.

Best regards,

Sam
On Tue, 22 Mar 2005 16:07:14 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Samuel R. Neff" <bl****@newsgroup.nospam> wrote in message
news:ia********************************@4ax.com.. .

Why would you cast two strings to objects to compare them? I saw code
in an MS sample on MSDN and don't get it.

if ( (object)name == (object)attr.name ) {

both "name" and "attr.name" are declared as string.


It is to circumvent operator overloading. By casting to object here, you
force the compiler to use objects == operator, which is a reference
comparison, whereas not casting would have used strings == operator, which
is a string comparison(full character to character compare). I don't know
specifically why the author felt reference comparison was important here(I
can't find it in your example), but that is the effect.

I personally prefer to use object.ReferenceEquals() instead of casting the
two instances to object.
http://msdn.microsoft.com/XML/Buildi...mlBkMkRead.asp

Thanks,

Sam

B-Line is now hiring one Washington D.C. area VB.NET
developer for WinForms + WebServices position.
Seaking mid to senior level developer. For
information or to apply e-mail resume to
sam_blinex_com.
Nov 17 '05 #3

P: n/a
Are strings compared using character-by-character comparison? Since the
CLR performs string folding, aren't all identical strings really the
same copy anyway? So doesn't == for strings just do a reference
comparison as it does for object?

I don't see the point of comparing strings character-by-character when
you know that all references to identical strings point to the same
memory location...?

Nov 17 '05 #4

P: n/a
This also raises a question about polymorphism and overloading. If I
cast an object up the class hierarchy, will an overloaded method be
called based on the type of the refrence, or based on the type of the
object? For example:

public class A
{
public static DoSomething(A theA) { Console.WriteLine("It's an
A!"); }
public static DoSomething(B theB) { Console.WriteLine("It's a B!");
}
}
public class B : A { ... }

B theB = new B();
A theA = theB;
A.DoSomething(theA);

The question is, which method will be invoked? Will the compiler invoke
DoSomething(A) because the reference it's being passed is an A, or will
it invoke DoSomething(B) because the object to which the reference
points is, in fact, a B?

Or, stated another way, is the call resolved at compile time, or at run
time?

Nov 17 '05 #5

P: n/a

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:OU**************@TK2MSFTNGP14.phx.gbl...
It is to circumvent operator overloading. By casting to object here, you
force the compiler to use objects == operator, which is a reference
comparison, whereas not casting would have used strings == operator, which
is a string comparison(full character to character compare). I don't know
specifically why the author felt reference comparison was important here(I
can't find it in your example), but that is the effect.


Uhhhm....I could be mistaken here but....

I thought string.Equals/op_Equality DID use reference comparison
<MEMORY>
Dotnet maintains a collection of strings currently in use
If you create a new string with exactly the same characters as an existing
string
a reference to the original will be returned. (Flyweight pattern)
Thus two strings with the EXACT same characters in the same sequence ARE the
same object.

This allows rapid string comparison (reference compare)
I am pretty sure that this also simplifies using strings in case statements
(within a switch).
<\MEMORY>

This, of course would not apply to case insensitive compares
And CompareTo would still need to test the strings on a per character basis.

I of course could be completely wrong...

Hope this helps
Bill

Nov 17 '05 #6

P: n/a

The issue that was confusing me is that override resolution is
different for operators and methods. Operators are static methods and
thus override resolution is done at compile time based on the casted
type. In my testing this is inconsistent with instance method
overrides which are resolved based on actual object type and not the
casted type.

Sam
On 23 Mar 2005 09:10:35 -0800, "Bruce Wood" <br*******@canada.com>
wrote:
This also raises a question about polymorphism and overloading. If I
cast an object up the class hierarchy, will an overloaded method be
called based on the type of the refrence, or based on the type of the
object? For example:

public class A
{
public static DoSomething(A theA) { Console.WriteLine("It's an
A!"); }
public static DoSomething(B theB) { Console.WriteLine("It's a B!");
}
}
public class B : A { ... }

B theB = new B();
A theA = theB;
A.DoSomething(theA);

The question is, which method will be invoked? Will the compiler invoke
DoSomething(A) because the reference it's being passed is an A, or will
it invoke DoSomething(B) because the object to which the reference
points is, in fact, a B?

Or, stated another way, is the call resolved at compile time, or at run
time?


B-Line is now hiring one Washington D.C. area VB.NET
developer for WinForms + WebServices position.
Seaking mid to senior level developer. For
information or to apply e-mail resume to
sam_blinex_com.
Nov 17 '05 #7

P: n/a
While coding some data handling classes I just answered my own
question.

Overload resolution works like this:

Which _method signature_ to call is resolved at compile time, based on
the type of the references / value types being passed as arguments.
Therefore, in my example, the compile will tell the run time to look
for a method called DoSomething that takes an argument of type "A",
because that is the type of the reference that was passed.

Polymorphism comes into play when you are invoking a method on an
_instance_. In other words, if you are calling method DoSomethingElse
that is an _instance method_ of A, and overridden in B, then the CLR
decides _at run time_ _which method to call_ based on the actual type
of the object on which the method is invoked. So,

A anA = new B();
A.DoSomethingElse(15);

will call B's "DoSomethingElse", not A's. So, putting it all together:

public class A
{
public virtual void DoSomethingElse(int arg) { ... }
public virtual void DoSomethingELse(double arg) { ... }
}

public class B : A
{
public override void DoSomethingElse(int arg) { ... }
public override void DoSomethingElse(double arg) { ... }
}

if you call

A myA = new B();
myA.DoSomethingElse((double)15);

the method invoked will be B's DoSomethingElse(double). The compiler
decides, at compile time, to invoke a DoSomethingElse that takes a
double parameter, based on the type passed as an argument. The CLR
decides, at run time, to invoke the DoSomethingElse(double) of B
because the object is really a B even though its reference is being
held in a variable of type A.

In the case of static methods, polymorphism doesn't come into play,
because there are no instances. So, everything about the call is
decided at compile time, based on the types of the arguments.

So, yes, saying

if ((object)string1 == (object)string2)

will, in fact, call Object's == operator. However, as I noted in
another post, this should do the same thing as string's == operator, so
I don't see the point.

Nov 17 '05 #8

P: n/a
Bruce Wood <br*******@canada.com> wrote:
Are strings compared using character-by-character comparison? Since the
CLR performs string folding, aren't all identical strings really the
same copy anyway? So doesn't == for strings just do a reference
comparison as it does for object?
No, because interning is only applied to string literals (and anything
you call Intern on manually).
I don't see the point of comparing strings character-by-character when
you know that all references to identical strings point to the same
memory location...?


They don't. Try the following:

using System;

public class Test
{
static void Main()
{
string x = "x";
string y = x+"y";
string z = x+"y";

Console.WriteLine (y==z);
Console.WriteLine ((object)y==(object)z);
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #9

P: n/a
Samuel R. Neff <bl****@newsgroup.nospam> wrote:
The issue that was confusing me is that override resolution is
different for operators and methods. Operators are static methods and
thus override resolution is done at compile time based on the casted
type.
I think you're confusing overriding and overloading. There's no such
thing as operator overriding in C# - but there *is* operator
overloading which, like method overloading, is resolved at compile
time.
In my testing this is inconsistent with instance method
overrides which are resolved based on actual object type and not the
casted type.


It's not inconsistent with overloading though :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #10

P: n/a
Bill Butler <Bi**@DigitalArts.com> wrote:
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:OU**************@TK2MSFTNGP14.phx.gbl...
It is to circumvent operator overloading. By casting to object here, you
force the compiler to use objects == operator, which is a reference
comparison, whereas not casting would have used strings == operator, which
is a string comparison(full character to character compare). I don't know
specifically why the author felt reference comparison was important here(I
can't find it in your example), but that is the effect.

Uhhhm....I could be mistaken here but....

I thought string.Equals/op_Equality DID use reference comparison


It will do as a first pass, but
<MEMORY>
Dotnet maintains a collection of strings currently in use
If you create a new string with exactly the same characters as an existing
string a reference to the original will be returned. (Flyweight pattern)
Only if the string is a literal.
Thus two strings with the EXACT same characters in the same sequence ARE the
same object.


Nope. That would be incredibly expensive to do *every* time a string
was built.

See my reply to Bruce for an example.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #11

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Bruce Wood <br*******@canada.com> wrote:

....
I don't see the point of comparing strings character-by-character when
you know that all references to identical strings point to the same
memory location...?


They don't. Try the following:

using System;

public class Test
{
static void Main()
{
string x = "x";
string y = x+"y";
string z = x+"y";

Console.WriteLine (y==z);
Console.WriteLine ((object)y==(object)z);
}
}

Thanks Jon,
I guess I should have tested before posting.
Do you happen to know the actual algorithm for string.Equals()?

I played around a bit and found that it checks for Length equality before
resorting to brute force

Bill


Nov 17 '05 #12

P: n/a
Bill Butler <Bi**@DigitalArts.com> wrote:
Thanks Jon,
I guess I should have tested before posting.
Do you happen to know the actual algorithm for string.Equals()?

I played around a bit and found that it checks for Length equality before
resorting to brute force


I don't know, but I can't imagine there'd be much that would be faster
than checking for reference equality, checking for length equality, and
then brute forcing the rest - at least not without making a guess as to
where any difference was most likely to be.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #13

P: n/a
Ah. Yes, that makes perfect sense, because performing interning at run
time on every string construction would be prohibitively expensive.
Silly me. :)

Nov 17 '05 #14

P: n/a

Actually as it turns out this is what is hapenning on the sample code
that was the original source of this thread. It's a sample XmlReader
implementation and a few lines above the comparison it has this:

// atomize the name
name = reader.NameTable.Get( name );

So that explains it--the strings are interned so can reference
checking is possible. Object.ReferenceEquals would have been clearer
though (as someone else said earlier).

Thanks for all the feedback,

Sam
On 23 Mar 2005 13:38:47 -0800, "Bruce Wood" <br*******@canada.com>
wrote:
Ah. Yes, that makes perfect sense, because performing interning at run
time on every string construction would be prohibitively expensive.
Silly me. :)


B-Line is now hiring one Washington D.C. area VB.NET
developer for WinForms + WebServices position.
Seaking mid to senior level developer. For
information or to apply e-mail resume to
sam_blinex_com.
Nov 17 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.