1

Why is this passing Assert.AreSame()?

[TestMethod]
public void StringSameTest()
{
      string a = "Hello";
      string b = "Hello";

      Assert.AreSame(a, b);
}

I understand ìt tests for reference equality, and is essentially the same as Assert.IsTrue(object.ReferenceEquals(a, b)) but it's clear that a and b are different string objects, regardless of them having the same values. If Ì set string b = a; I'd expect true, but that's not the case. Why isn't this test failing?

Thanks

1 Answers1

3

The C# compiler will intern identical literal strings to the same const string reference.

So your code is equivalent to this:

private const String _hello = "Hello";

[TestMethod]
public void StringSameTest()
{
      string a = _hello;
      string b = _hello;

      Assert.AreSame( a, b ); // true
}

To create a separate string instance that's identical to a const string use String.Copy():

string a = "Hello";
string b = a.Copy();

Assert.AreSame( a, b ); // false

However, do note that:

  • String.Copy() and String.Clone() are different!
    • Clone() does not actually clone the string value, it instead returns a reference to itself.
    • String.ToString() also returns a reference to itself.
  • String.Copy() is deprecated in .NET Framework and .NET Core and may be removed in a future version.

See Do string literals get optimised by the compiler?

Dai
  • 141,631
  • 28
  • 261
  • 374
  • 1
    Huh, looks like the C# compiler is a lot smarter than I am. Can you speak more about the *intern*? I've never heard of that word in this context. Every time I search "Compiler intern" on Google I get a list of job adverts for a compiler developer. –  Feb 02 '20 at 02:56
  • @TeeZadAwk Search for "string intern c#" – vasil oreshenski Feb 02 '20 at 03:00