Testing strings

Generally I have been testing a string like:

 if (mystring=="APPLE") 
 {
    beeptwice();
}

I saw this interesting post:

[quote]You do a compare [italic]if (r == “T”)[/italic] to see if a ‘T’ has been received. You should be doing the compare as [italic]if (t.Equals(“T”))[/italic]. What you did was comparing references not the content of the strings.
[/quote]

I have been totally unaware of .Equals, so should I be doing the following (does it make a difference or offer any speed improvement)??

if (mystring.Equals("APPLE")) 
 {
    beeptwice();
}

He’s so wrong, consider this example:


class Program
{
    class A
    {
        public string Name;
    }

    static void Main(string[] args)
    {
        A a1 = new A();
        A a2 = new A();
        a1.Name = "Test";
        a2.Name = "Test";

        if (a1 == a2)
            Debug.Print("EQUAL");
        else
            Debug.Print("NOT EQUAL");

        if (a1.Name == a2.Name)
            Debug.Print("EQUAL");
        else
            Debug.Print("NOT EQUAL");
    }
}

The first test (a1 == a2) will fail because you are comparing object references there, the second test will succeed because strings are a special case (just like integral types, int, byte, short, etc) and will be compared by value.

If that post was correct (about comparing references vs values) the below would fail as well, wouldn’t it (unless I am missing something)


int a = 0;
int b = 0;

if (a == b)
   Debug.Print("A == B");
else
   Debug.Print("A != B");

If I am correct, inherent value (forgot the exact term) types (int, string, etc) are treated differently when doing comparisons. They don’t compare the object reference, but the value. As Wouter pointed out other object types do indeed compare reference to see if the variables are referencing the same object in memory).

ummm…

What is .Equals used for? are there some examples?

Beyond the documentation - I don’t know:

[quote=“MSDN”]
Equals Determines whether two specified String objects have the same value.
Equals (Inherited from Object.) [/quote]

Guessing it’s a string specific implementation of base’s object class for comparing 2 string values. I’m guessing (a lot of that going on here) that the == operator may even call the .Equals method on the string object.

Not a bad guess!

I see this…


HRESULT Library_corlib_native_System_String::Equals___STATIC__BOOLEAN__STRING__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    stack.SetResult_Boolean( CLR_RT_HeapBlock::Compare_Unsigned_Values( stack.Arg0(), stack.Arg1() ) == 0 );

    TINYCLR_NOCLEANUP_NOLABEL();
}

HRESULT Library_corlib_native_System_String::op_Equality___STATIC__BOOLEAN__STRING__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    TINYCLR_SET_AND_LEAVE(Library_corlib_native_System_String::Equals___STATIC__BOOLEAN__STRING__STRING( stack ));

    TINYCLR_NOCLEANUP();
}

…at http://netmf.codeplex.com/SourceControl/changeset/view/21675#8799 which looks exactly like your guess. (edit: …and these seem to be the innards of .Equals and ==, with == just calling .Equals)

Equals is an overridable method of object. As everything in c# is derived from object, they all have the Equals method. This allows you to override it in your own custom class to be able to value compare two instances.

are there any examples of using .Eqauls with strings…I haven’t seen it used much, is it somethinig that should be used more often? What , if any are the advantages?

@ Hoyt

I’m no expert, but I think reply number 6 at this link illustrates the proper use of == and Equal:

This reply illustrates a case where two string variables are being compared, and one of them happens to be set to null.
if string a happens to be null, then a.Equals(b) would throw an exception.

Here is an argument for using == instead of Equals():

Suppose you are passed two string variables and you need to compare them for equality in your method. If you use a.Equals(b), and don’t check for null first, then you may end up throwing an exception. However, if you use the == operator, then the comparison will be done correctly and will not throw an exception.

Here is an argument for using Equals:

If you need to do a value comparison of two variables, and don’t know the exact type of each variable, then implement code that is similar to the code listed in the link above for the == operator.


if (object.ReferenceEquals(left, null) && object.ReferenceEquals(right, null))
    return true; 
if (object.ReferenceEquals(left, null))
    return right.Equals(left); 
return left.Equals(right); 

If left is null, but right is not, then there’s no reason to call right.Equals(left), you can immediately return false (at least in the general case). Try this instead:


if( object.ReferenceEquals(left, right) )    // covers the both-are-null case
    return true;
else if( object.ReferenceEquals(left, null) || object.ReferenceEquals(right, null) )
    return false;
else
    return left.Equals(right);

Just for strings? No, not really: the underlying code for == and for .Equals basically end up in the same place and, like others said, using .Equals opens you up to null reference exceptions that you won’t get with ==.

Other object types can behave differently. In C#, you can write your own code for .Equals and to overload operators like == in your classes. Other classes can do the same. For the string class, they made == and .Equals the same.

In my experience, the normal to implement .Equals() and == is to implement .Equals() and then have == check for nulls then call .Equals() (like in the previous examples).

Having a class implement different semantics for .Equals() and == would be confusing, to say the least. It’s definitely not the norm.

Hi godefroi,

Yes, your implementation makes more sense :slight_smile:

Jim