C# Tips

Today's C# Tip

C#: The pitfall of equality operator

I ran into equality operator (==) issue again. That is, when equality operator compares different types, more attention should be given.

Here is an example. Let's assume that rs["xtype"] returns a string "Private." If so, will Block A be run?

SqlDataReader rs = cmd.ExecuteReader();
rs.Read();

object xtype = rs["xtype"].ToString(); // returns "Private"
if (xtype == "Private")  // is it true?
{
	// Block A
}

Obviously rs["xtype"].ToString() return a string type with its value "Private," and then if condition seems to be true. But actually it is false and it will never be true no matter what value the variable xtype has.

Let's go to the basics. Here is how equality operator works:

  1. For value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise.
  2. For reference types other than string, == returns true if its two operands refer to the same object.
  3. For the string type, == compares the values of the strings.

 

The variable xtype is object type (even if it contains string data) and literal "Private" is string type. So it belongs to rule 2. The equality operator will return true when two operands shall point to the same object, and obviously they point to two different objects. So it always returns false.

Let's look at one more example. Here we have object a and b whose values are the same. Will it return true?

object a = "Hello";
object b = "Hello";
return a == b;

Right, it returns true. Why? Some people would guess so because both have the same word. But no, it is not because of that. Since both types are object type, equality operator checks to see if each points to the same object. Do they refer to same object? Yes, they are. This is because of string interning. (String Interning: The CLR automatically maintains a table, called the intern pool, which contains a single instance of each unique literal string constant declared in a program, as well as any unique instance of String you add programmatically by calling the String.Intern method.) Because both "Hello" refer to the same literal constant in intern pool, object a and b actually points to the same object. Hence, it is true.