StringBuilder는 일정하게 메모리를 할당해서 실제보다 더 많은 메모리를 사용한다. 이 때 들어가는 게 Capacity 개념이다.
StringBuilder sb1 = new StringBuilder("abc");
StringBuilder sb2 = new StringBuilder("abc", 16);
Console.WriteLine();
Console.WriteLine("a1) sb1.Length = {0}, sb1.Capacity = {1}",
sb1.Length, sb1.Capacity)
// a1) sb1.Length = 3, sb1.Capacity = 16
String과 string은 같다.
$”{문자열 아닌 타입}”는 String.Format()과 동일하다.
String의 += 연산자는 Concat과 완전히 동일한 개념이다. 그리고, Concat은 문자열을 힙에 새로 생성한다. 그러므로 기존의 “abc”는 Immutable하다.
void Main()
{
string str_1 = "abc";
string str_2 = str_1;
str_1 += "def";
str_1.Dump(); //abcdef
str_2.Dump(); //abc
}

String은 new로 선언 하지 않는다.
거의 모든 타입에 대해서 ToString()은 동작한다. 모든 수치 타입에 대해서는 Parse가 동작한다.
문자열 인터닝 = 같은 문자열은 힙에 하나만 저장하고 해시테이블을 통해 하나만 존재하도록 관리한다.
void Main()
{
// 같은 문자열이고, 컴파일러가 내부적으로 Intern을 호출한다.
// Intern은 문자열 해시테이블에 있는지 확인하는 정적메서드
string str1 = "abc";
string str2 = "abc";
if(str1.Equals(str2))
{
"same string".Dump();
}
if(object.ReferenceEquals(str1,str2))
{
"ref same string".Dump();
}
}
// same string
// ref same string
string 객체에 대해서 .AsSpan(startIdx , length)으로 생성한다.