Память выделяется только один раз из-за того, как CLR использует Intern Pool для дублирующихся строковых значений. Ссылка на обе строки будет одинаковой.
Проверьте ссылку, используя - Object.ReferenceEquals(str1, str2);
Если вы используете код, указанный ниже, чтобы получить место в памяти, на которое указывают ссылки, оно будет таким же.
string myVar = "This is my string";
string myVar1 = myVar;
unsafe
{
TypedReference tr = __makeref(myVar);
IntPtr ptr = **(IntPtr**)(&tr);
TypedReference tr1 = __makeref(myVar1);
IntPtr ptr1 = **(IntPtr**)(&tr1);
Console.WriteLine(ptr);
Console.WriteLine(ptr1);
}
Местоположение памяти, на которое они указывают, одинаково. Значение сохраняется в памяти только один раз.
Если вы присваиваете ту же строку другим переменным, то такая же ссылка берется из внутреннего пула и присваивается строковой переменной.