C#.NET offers a variety of ways of testing for equality. For the most part, things just work as the programmer would expect. But, because the 
For starters, just what does the
For your own classes, you can override the
If the
Note that
Ok, so you can use the
That works, but should you do that? I say "no". Why? The reason is simple: because Visual Studio will underline that code with a green squiggly line, and when you mouse over it the tooltip says "Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'string'". Basically, they are telling you that something is "fishy" and that means it does not fall under best practices.
By now. You may be asking yourself If the cast-trick above is not best practices, how do I compare two strings to see if they reference the same value? OR, If the
The
There are a few more things to be aware about when it comes to comparisons using the
So now think back to that
That pretty much covers a few of the basics of comparisons in .NET. But, once again, string comparisons prevent a host of problems. Do you want to do a case-sensitive or insensitive comparison? What about cultural based comparisons? To see if you will get burnt by a Turkey, see the blog post from my colleague Jeff Moser in the office next to me.
== operator and Equals() method can be overriden, some guidelines have been established by Microsoft to ensure that things continue to work as expected.For starters, just what does the
== operator do?  Well, that depends on what type of data you are dealing.  For the predefined value types, the == operator returns true of the values are equal.  For predefined reference types (except strings), the == operator returns true if both sides reference the same object.  And, the System.String class (a predefined, immutable reference type) overrides the == operator to return true if both sides have the same value.For your own classes, you can override the
== operator to do a value comparison instead of a reference comparison, but that does not mean you should! You should seriously think twice before doing that because most programmers will assume it is still a reference comparison.If the
System.String overrides == to compare string values, just what does it mean for two strings to have the same value?  The string's == operator actually calls the static String.Equals(string, string) method.  And, that method will return true if...- Both parameters are null
- Both parameters reference the same object
- Both parameters are have the same number of characters (i.e. same length) and the ordinal value of each character is the same
Note that
String.Equals() compares the ordinal value.  This means that the comparison is inherently case-sensitive and culture-insensitive.  That is, the Unicode values of the characters at each position in the two strings must be same.Ok, so you can use the
== operator to compare the value of two strings. But, what if you want actually do want to compare two string variables to see if they reference the same thing? One common "trick" people do is to cast one (or both) of the string variables to an object.  Because one side is now an object, the compiler will use System.Object's == operator instead of the System.String operator to do that comparison, and that operator will do a reference comparison.
bool flag = (object)a == b;
That works, but should you do that? I say "no". Why? The reason is simple: because Visual Studio will underline that code with a green squiggly line, and when you mouse over it the tooltip says "Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'string'". Basically, they are telling you that something is "fishy" and that means it does not fall under best practices.
By now. You may be asking yourself If the cast-trick above is not best practices, how do I compare two strings to see if they reference the same value? OR, If the
== operator may have been overridden to compare values, how do I know I am actually comparing references?  Truth-be-told, the answer to both of those questions is the same:  use the static System.Object.ReferenceEquals() method instead.The
Object.ReferenceEquals() method unequivocally compares two references to see if they reference to the same instance an object. With normal objects, this is pretty straight-forward to understand. But, once again, things actually get a bit tricky with strings as is shown in the example below.
string a = "12";
string b = "1" + "2";
string c = "1"; c += "2";
// flagA1, flagA2, flagA3 and flagA4 are all true
// because they were all assigned by value comparisons.
bool flagA1 = (a == "12");
bool flagA2 = (a == a);
bool flagA3 = (a == b);
bool flagA4 = (a == c);
// flagB1, flagB2 and flagB3 are all true because the
// compiler interns the variables a & b and literal "12"
// to the same string.
bool flagB1 = object.ReferenceEquals(a, "12");
bool flagB2 = object.ReferenceEquals(a, a);
bool flagB3 = object.ReferenceEquals(a, b);
// flagB4 is false because variable c was created by
// concatenating two values at run-time, and therefore
// is not interned to the same "12" as variables a & b
// literal "12". Sure, variable b was concatenated too,
// but that was at compile time so it was still interned.
bool flagB4 = object.ReferenceEquals(a, c);
There are a few more things to be aware about when it comes to comparisons using the
== operator.  Ever here of boxing and unboxing?  The == operator will compare the values of two value-type parameters, but boxed parameters are no longer value type parameters!
bool CompareBoxedValues(object a, object b)
{
return (a == b);
}
int a = 1;
int b = 1;
// flag1 is true because the two values are equal
bool flag1 = (a == b);
// flag2 is false because the two variables are boxed
// into different objects
bool flag2 = CompareBoxedValues(a, b);
// flag3 is also false because the same variable is
// boxed into two different objects
bool flag3 = CompareBoxedValues(a, a);
So now think back to that
Object.ReferenceEquals() method. What do you think happens if you pass non-references (i.e. values) into it? Sure enough, each value gets boxed into a different object instance so the method always returns false!
// The following always sets flag to false
int a = 1;
bool flag = ReferenceEquals(a, a);
That pretty much covers a few of the basics of comparisons in .NET. But, once again, string comparisons prevent a host of problems. Do you want to do a case-sensitive or insensitive comparison? What about cultural based comparisons? To see if you will get burnt by a Turkey, see the blog post from my colleague Jeff Moser in the office next to me.
 
                    
                     
                    
                 
                    
                 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号