Wednesday, March 28, 2012

string.equals general question

hi

there's something with the following I just can't seem to understand.

Private Function stringequals() As String

Dim str1 As String = "aaa"
Dim str2 As String = "bbb"
Dim str3 As String = "ccc"
Dim str4 As String = "aaa"

str1 &= str1.Equals(str2, str3)

Return str1

End Function

This function returns the string 'aaaFalse', as I was expecting. What I dont understadn is this;

The Equals method is overloaded so that I can compare two objects, as I'm doing here with str2 and str3. I can't see why they've done this. str2 and str3 have NOTHING to do with str1.

I'd understand if the line was;

str1 &= str1.Equals(str4)

Of course, this is a valid overload method too.

I'm only really asking my question because I'm new to vb.net and OO in general. The str1.Equals method is 'part' of str1, but compares two different obects (str2 and str3). This doesnt make sense to me.

any thoughts?

thanks

mauriceI think that two things are throwing you.

First, you have used the &= operator which means, "add to" ...

str1 &= str2 means"aaa" + "bbb" and will give you"aaabbb"
str1 &= False means"aaa" + "False" and will give you"aaaFalse"

The last example is why you are getting "aaa" in your result.

The second thing I think is throwing you is what, exactly, the.Equals is doing. It compares the thing before .Equals to the thing in the brackets.

If there is only one thing in the brackets, then it works simply:
str1.Equals("aaa") asks whether"aaa" = "aaa" and the answer isTrue
str1.Equals(str2) asks whether"aaa" = "bbb" and the answer isFalse

But, if there are two things in the brackets, it compares all three things (this is notstrictly true, but it's true enough with the example you've provided):
str1.Equals("aaa", str4) asks whether"aaa" = "aaa" = "aaa" and the answer isTrue
str1.Equals(str3, str4) asks whether"aaa" = "ccc" = "aaa" and the answer isFalse

So, your expressionstr1 &= str1.Equals(str2, str3") is working like this:

str1.Equals(str2, str3") asks whether"aaa" = "bbb" = "ccc" which isFalse.

So, your expression reduces tostr1 &= False.

Remember that the &= operator means to add the second thing to the first, so:
str1 &= False means"aaa" + "False" which becomes"aaaFalse"

Has that helped explain what, exactly, is going on?
Actually, not true.

str1.Equals(str2,str3) compares ONLY str2 and str3.

While this implementation might seem a tad confusing, this is only from the perspective you are using it here.

.Equals is implemented as a shared method, so you don't need to instantiate the string object to use it. For example:

blnStringComp = String.Equals(str2,str3)

You might use it in this fashion to compare, say, the content of two textboxes, without creating an explicit instance of the string class to do so:

blnStringCompare = String.Equals(Me.txt1.Text, Me.txt2.Text)

Is it a bit superfluous? Perhaps. I think a better question is (and I ask this seriously), is String.Equals faster than just using the "=" operator.
I said that my explanation wasn't strictly true ... but, you're right, it's not even "almost true" :)

You're also right ... simply using a set of "=" operator tests would be easier. However, I think that String.Equals is probably faster over a number of boolean tests, in the same way that the StringBuilder class is faster than "&=" for more than handful of string concatenations.
thanks for your answers, i thought something 'strange' was going on...

"Equals is implemented as a shared method, so you don't need to instantiate the string object to use it. For example:

blnStringComp = String.Equals(str2,str3)"

now it all makes sense, mostly ;)
An intresting aside

In a (good?) OO language like C# the above wont compile, and thus remove the potential misunderstsanding of what is happening.

One can't call static (shared) members on an instance of a class, only on the type.

Another gotcha, the object.equals(obj1, obj2) will only do a reference equals, ie are the objects the same (ie the same address), not a value equals, do the objects have the same value. The string.equals(string1, string2) will do a value equals. I imagine this is what is called in the above instances.

M G Walmsley
Thatwas interesting.

You mentioned that .Equals tests references, not values. You then explain that the reference test asks "are the objects the same (ie the same address)". By "the same address", do you mean the "address" as used inAddHandler btnSend.Click, AddressOf btnSend_Click? If so, it means I've misunderstood the difference between ByVal and ByRef...
By address i mean the address in memory of the object. Normally this is not available or needed in code, but can be got at if needed. This is returned by AddressOf, though strictly this is a function delegate, ie the address and signature of the function.

By Ref means that the address (as above) is passed to the function. So code inside the called function will update the object in the callee.

For Reference objects, eg, classes, this is the normal way to pass them to functions.
Value types, primitives, ints etc, and structures are normally passed By Value not By Ref.

By Value means the value of the object is passed. IF an object is passed by value, it is copied to a new object. This means the object in the callee will not be updated in the called function.
Another thing to be carefull about.

All types derive from object. Object has a Equals method that works as described (a reference equals).

So all types have a Equals method. So unless they are overridden be a derived type, the base object.Equals will be called.

String does have an override of Equals which does a value equals, but only if called with two strings.

The thing to always be aware of when one writes a statement like xxx.Equals(aaa, bbb) is what will actually be called.
Thanks, mgwalm, for your explanation.

For this cowboy (self-taught) developer, it shows how much I don't know about the very fundamentals of programming :/

0 comments:

Post a Comment