<p>Comparing string in C# is pretty simple.  In fact there are several ways to do it.  I have listed some in the block below.  What I am curious about are the differences between them and when one should be used over the others?  Should one be avoided at all costs?  Are there more I haven't listed?  </p>

<pre><code>string testString = "Test";
string anotherString = "Another";

if (testString.CompareTo(anotherString) == 0) {}
if (testString.Equals(anotherString)) {}
if (testString == anotherString) {}
</code></pre>

<p>(Note: I am looking for equality in this example, not less than or greater than but feel free to comment on that as well)</p>

[{'answer_id': 44301, 'author': 'Ed S.', 'author_id': 1053, 'author_profile': 'https://Stackoverflow.com/users/1053', 'pm_score': 6, 'selected': False, 'text': '<p>From MSDN:</p>\n\n<blockquote>\n  <p>"The CompareTo method was designed primarily for use in sorting or\n  alphabetizing      operations. It should not be used when the primary\n  purpose of the method call is to     determine whether two strings are\n  equivalent. To determine whether two strings are    equivalent, call\n  the Equals method."</p>\n</blockquote>\n\n<p>They suggest using <code>.Equals</code> instead of <code>.CompareTo</code> when looking solely for equality.  I am not sure if there is a difference between <code>.Equals</code> and <code>==</code> for the <code>string</code> class.  I will sometimes use <code>.Equals</code> or <code>Object.ReferenceEquals</code> instead of <code>==</code> for my own classes in case someone comes along at a later time and redefines the <code>==</code> operator for that class.</p>\n'}, {'answer_id': 44303, 'author': 'OwenP', 'author_id': 2547, 'author_profile': 'https://Stackoverflow.com/users/2547', 'pm_score': 3, 'selected': False, 'text': "<p>In the forms you listed here, there's not much difference between the two.  <code>CompareTo</code> ends up calling a <code>CompareInfo</code> method that does a comparison using the current culture; <code>Equals</code> is called by the <code>==</code> operator.</p>\n\n<p>If you consider overloads, then things get different.  <code>Compare</code> and <code>==</code> can only use the current culture to compare a string.  <code>Equals</code> and <code>String.Compare</code> can take a <code>StringComparison</code> enumeration argument that let you specify culture-insensitive or case-insensitive comparisons.  Only <code>String.Compare</code> allows you to specify a <code>CultureInfo</code> and perform comparisons using a culture other than the default culture.</p>\n\n<p>Because of its versatility, I find I use <code>String.Compare</code> more than any other comparison method; it lets me specify exactly what I want.</p>\n"}, {'answer_id': 44349, 'author': 'hometoast', 'author_id': 2009, 'author_profile': 'https://Stackoverflow.com/users/2009', 'pm_score': -1, 'selected': False, 'text': '<p>Using .Equals is also a lot easier to <em>read</em>.</p>\n'}, {'answer_id': 44367, 'author': 'viggity', 'author_id': 4572, 'author_profile': 'https://Stackoverflow.com/users/4572', 'pm_score': 3, 'selected': False, 'text': "<p>Not that performance usually matters with 99% of the times you need to do this, but if you had to do this in a loop several million times I would highly suggest that you use .Equals or == because as soon as it finds a character that doesn't match it throws the whole thing out as false, but if you use the CompareTo it will have to figure out which character is less than the other, leading to slightly worse performance time.</p>\n\n<p>If your app will be running in different countries, I'd recommend that you take a look at the CultureInfo implications and possibly use .Equals. Since I only really write apps for the US (and don't care if it doesn't work properly by someone), I always just use ==.</p>\n"}, {'answer_id': 44373, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 9, 'selected': True, 'text': "<p>Here are the rules for how these functions work:</p>\n\n<p><strong><code>stringValue.CompareTo(otherStringValue)</code></strong></p>\n\n<ol>\n<li><code>null</code> comes before a string</li>\n<li>it uses <code>CultureInfo.CurrentCulture.CompareInfo.Compare</code>, which means it will use a culture-dependent comparison. This might mean that <code>ß</code> will compare equal to <code>SS</code> in Germany, or similar</li>\n</ol>\n\n<p><strong><code>stringValue.Equals(otherStringValue)</code></strong></p>\n\n<ol>\n<li><code>null</code> is not considered equal to anything</li>\n<li>unless you specify a <code>StringComparison</code> option, it will use what looks like a direct ordinal equality check, i.e. <code>ß</code> is not the same as <code>SS</code>, in any language or culture</li>\n</ol>\n\n<p><strong><code>stringValue == otherStringValue</code></strong></p>\n\n<ol>\n<li>Is not the same as <code>stringValue.Equals()</code>.</li>\n<li>The <code>==</code> operator calls the static <code>Equals(string a, string b)</code> method (which in turn goes to an internal <code>EqualsHelper</code> to do the comparison.</li>\n<li>Calling <code>.Equals()</code> on a <code>null</code> string gets <code>null</code> reference exception, while on <code>==</code> does not.</li>\n</ol>\n\n<p><strong><code>Object.ReferenceEquals(stringValue, otherStringValue)</code></strong></p>\n\n<p>Just checks that references are the same, i.e. it isn't just two strings with the same contents, you're comparing a string object with itself.</p>\n\n<hr>\n\n<p>Note that with the options above that use method calls, there are overloads with more options to specify how to compare.</p>\n\n<p>My advice if you just want to check for equality is to make up your mind whether you want to use a culture-dependent comparison or not, and then use <code>.CompareTo</code> or <code>.Equals</code>, depending on the choice.</p>\n"}, {'answer_id': 513072, 'author': 'max', 'author_id': 59407, 'author_profile': 'https://Stackoverflow.com/users/59407', 'pm_score': 6, 'selected': False, 'text': '<p>If you are ever curious about differences in BCL methods, <a href="http://www.red-gate.com/products/reflector/" rel="noreferrer">Reflector</a> is your friend :-)</p>\n\n<p>I follow these guidelines:</p>\n\n<p><strong>Exact match:</strong> <sub>EDIT: I previously always used == operator on the principle that inside Equals(string, string) the object == operator is used to compare the object references but it seems strA.Equals(strB) is still 1-11% faster overall than string.Equals(strA, strB), strA == strB, and string.CompareOrdinal(strA, strB).  I loop tested with a StopWatch on both interned/non-interned string values, with same/different string lengths, and varying sizes (1B to 5MB).</sub></p>\n\n<pre><code>strA.Equals(strB)\n</code></pre>\n\n<p><strong>Human-readable match (Western cultures, case-insensitive):</strong></p>\n\n<pre><code>string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0\n</code></pre>\n\n<p><strong>Human-readable match (All other cultures, insensitive case/accent/kana/etc defined by CultureInfo):</strong></p>\n\n<pre><code>string.Compare(strA, strB, myCultureInfo) == 0\n</code></pre>\n\n<p><strong>Human-readable match with custom rules (All other cultures):</strong></p>\n\n<pre><code>CompareOptions compareOptions = CompareOptions.IgnoreCase\n                              | CompareOptions.IgnoreWidth\n                              | CompareOptions.IgnoreNonSpace;\nstring.Compare(strA, strB, CultureInfo.CurrentCulture, compareOptions) == 0\n</code></pre>\n'}, {'answer_id': 513103, 'author': 'Jonathan C Dickinson', 'author_id': 24064, 'author_profile': 'https://Stackoverflow.com/users/24064', 'pm_score': 4, 'selected': False, 'text': '<p>As <a href="https://stackoverflow.com/questions/44288/differences-in-string-compare-methods-in-c/44301#44301" title="Answer">Ed</a> said, CompareTo is used for sorting.</p>\n\n<p>There is a difference, however, between .Equals and ==.</p>\n\n<p>== resolves to <em>essentially</em> the following code:</p>\n\n<pre><code>if(object.ReferenceEquals(left, null) &amp;&amp; \n   object.ReferenceEquals(right, null))\n    return true;\nif(object.ReferenceEquals(left, null))\n    return right.Equals(left);\nreturn left.Equals(right);\n</code></pre>\n\n<p>The simple reason is the following will throw an exception:</p>\n\n<pre><code>string a = null;\nstring b = "foo";\n\nbool equal = a.Equals(b);\n</code></pre>\n\n<p>And the following will not:</p>\n\n<pre><code>string a = null;\nstring b = "foo";\n\nbool equal = a == b;\n</code></pre>\n'}, {'answer_id': 2515930, 'author': 'David', 'author_id': 301718, 'author_profile': 'https://Stackoverflow.com/users/301718', 'pm_score': -1, 'selected': False, 'text': '<p>with .Equals, you also gain the StringComparison options. very handy for ignoring case and other things.</p>\n\n<p>btw, this will evaluate to false</p>\n\n<pre><code>string a = "myString";\nstring b = "myString";\n\nreturn a==b\n</code></pre>\n\n<p>Since == compares the values of a and b (which are pointers) this will only evaluate to true if the pointers point to the same object in memory. .Equals dereferences the pointers and compares the values stored at the pointers. \na.Equals(b) would be true here.</p>\n\n<p>and if you change b to:</p>\n\n<pre><code>b = "MYSTRING";\n</code></pre>\n\n<p>then a.Equals(b) is false, but</p>\n\n<pre><code>a.Equals(b, StringComparison.OrdinalIgnoreCase) \n</code></pre>\n\n<p>would be true</p>\n\n<p>a.CompareTo(b) calls the string\'s CompareTo function which compares the values at the pointers and returns &lt;0 if the value stored at a is less than the value stored at b, returns 0 if a.Equals(b) is true, and >0 otherwise. However, this is case sensitive, I think there are possibly options for CompareTo to ignore case and such, but don\'t have time to look now. \nAs others have already stated, this would be done for sorting. Comparing for equality in this manner would result in unecessary overhead.</p>\n\n<p>I\'m sure I\'m leaving stuff out, but I think this should be enough info to start experimenting if you need more details.</p>\n'}, {'answer_id': 15271318, 'author': 'Ryszard Dżegan', 'author_id': 2042090, 'author_profile': 'https://Stackoverflow.com/users/2042090', 'pm_score': 4, 'selected': False, 'text': '<p>Good explanation and practices about string comparison issues may be found in the article <a href="http://msdn.microsoft.com/en-us/library/ms973919.aspx" rel="noreferrer">New Recommendations for Using Strings in Microsoft .NET 2.0</a> and also in <a href="http://msdn.microsoft.com/en-us/library/dd465121.aspx" rel="noreferrer">Best Practices for Using Strings in the .NET Framework</a>.</p>\n\n<hr>\n\n<p>Each of mentioned method (and other) has particular purpose. The key difference between them is what sort of <a href="http://msdn.microsoft.com/en-us/library/System.StringComparison.aspx" rel="noreferrer">StringComparison Enumeration</a> they are using by default. There are several options:</p>\n\n<ul>\n<li>CurrentCulture</li>\n<li>CurrentCultureIgnoreCase</li>\n<li>InvariantCulture</li>\n<li>InvariantCultureIgnoreCase</li>\n<li>Ordinal</li>\n<li>OrdinalIgnoreCase</li>\n</ul>\n\n<p>Each of above comparison type targets different use case:</p>\n\n<ul>\n<li>Ordinal\n\n<ul>\n<li>Case-sensitive internal identifiers</li>\n<li>Case-sensitive identifiers in standards like XML and HTTP</li>\n<li>Case-sensitive security-related settings</li>\n</ul></li>\n<li>OrdinalIgnoreCase\n\n<ul>\n<li>Case-insensitive internal identifiers</li>\n<li>Case-insensitive identifiers in standards like XML and HTTP</li>\n<li>File paths (on Microsoft Windows)</li>\n<li>Registry keys/values</li>\n<li>Environment variables</li>\n<li>Resource identifiers (handle names, for example)</li>\n<li>Case insensitive security related settings</li>\n</ul></li>\n<li>InvariantCulture or InvariantCultureIgnoreCase\n\n<ul>\n<li>Some persisted linguistically-relevant data</li>\n<li>Display of linguistic data requiring a fixed sort order</li>\n</ul></li>\n<li>CurrentCulture or CurrentCultureIgnoreCase\n\n<ul>\n<li>Data displayed to the user</li>\n<li>Most user input</li>\n</ul></li>\n</ul>\n\n<p>Note, that <a href="http://msdn.microsoft.com/en-us/library/System.StringComparison.aspx" rel="noreferrer">StringComparison Enumeration</a> as well as overloads for string comparison methods, exists since .NET 2.0.</p>\n\n<hr>\n\n<h2><a href="http://msdn.microsoft.com/en-us/library/35f0x18w.aspx" rel="noreferrer">String.CompareTo Method (String)</a></h2>\n\n<p>Is in fact type safe implementation of <a href="http://msdn.microsoft.com/en-us/library/43hc6wht.aspx" rel="noreferrer">IComparable.CompareTo Method</a>. Default interpretation: CurrentCulture.</p>\n\n<p>Usage:</p>\n\n<blockquote>\n  <p>The CompareTo method was designed primarily for use in sorting or alphabetizing operations</p>\n</blockquote>\n\n<p>Thus</p>\n\n<blockquote>\n  <p>Implementing the IComparable interface will necessarily use this method</p>\n</blockquote>\n\n<h2><a href="http://msdn.microsoft.com/en-us/library/system.string.compare.aspx" rel="noreferrer">String.Compare Method</a></h2>\n\n<p>A static member of <a href="http://msdn.microsoft.com/en-us/library/system.string.aspx" rel="noreferrer">String Class</a> which has many overloads. Default interpretation: CurrentCulture.</p>\n\n<blockquote>\n  <p>Whenever possible, you should call an overload of the Compare method that includes a StringComparison parameter.</p>\n</blockquote>\n\n<h2><a href="http://msdn.microsoft.com/en-us/library/858x0yyx.aspx" rel="noreferrer">String.Equals Method</a></h2>\n\n<p>Overriden from Object class and overloaded for type safety. Default interpretation: Ordinal.\nNotice that:</p>\n\n<blockquote>\n  <p>The String class\'s equality methods include the <strong>static Equals</strong>, the <strong>static operator ==</strong>, and the <strong>instance method Equals</strong>.</p>\n</blockquote>\n\n<hr>\n\n<h2><a href="http://msdn.microsoft.com/en-us/library/system.stringcomparer.aspx" rel="noreferrer">StringComparer class</a></h2>\n\n<p>There is also another way to deal with string comparisons especially aims to sorting:</p>\n\n<blockquote>\n  <p>You can use the <a href="http://msdn.microsoft.com/en-us/library/system.stringcomparer.aspx" rel="noreferrer">StringComparer class</a> to create a type-specific comparison to sort the elements in a generic collection. Classes such as Hashtable, Dictionary, SortedList, and SortedList use the StringComparer class for sorting purposes.</p>\n</blockquote>\n'}, {'answer_id': 17361588, 'author': 'Rauld', 'author_id': 634031, 'author_profile': 'https://Stackoverflow.com/users/634031', 'pm_score': 2, 'selected': False, 'text': '<p>One BIG difference to note is .Equals() will throw an exception if first string is null, Whereas == will not.</p>\n\n<pre><code>       string s = null;\n        string a = "a";\n        //Throws {"Object reference not set to an instance of an object."}\n        if (s.Equals(a))\n            Console.WriteLine("s is equal to a");\n        //no Exception\n        if(s==a)\n            Console.WriteLine("s is equal to a");\n</code></pre>\n'}, {'answer_id': 47819977, 'author': 'John DiFini', 'author_id': 6230654, 'author_profile': 'https://Stackoverflow.com/users/6230654', 'pm_score': 1, 'selected': False, 'text': '<ul>\n<li><strong>s1.CompareTo(s2):</strong>  Do NOT use if primary purpose is to determine whether two strings are equivalent</li>\n<li><strong>s1 == s2:</strong>  Cannot ignore case</li>\n<li><strong>s1.Equals(s2, StringComparison):</strong>  Throws NullReferenceException if s1 is null</li>\n<li><strong>String.Equals(s2, StringComparison):</strong>  By process of eliminiation, this <em>static</em> method is the <strong>WINNER</strong> (assuming a typical use case to determine whether two strings are equivalent)!</li>\n</ul>\n'}]
['https://Stackoverflow.com/questions/44288', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2894/']