Почему StringBuilder при вызове метода ToString() копирует содержимое?
String и char[] это разные вещи с точки зрения среды выполнения. char[] это изменяемый объект, можно по индексу изменить значение отдельного элемента. String это неизменяемый объект, операции изменения строки на самом деле создают копии оригинального объекта строки.
Поэтому, если нужно создать строку через множество операций, используют StringBuilder, чтобы не было множества выделений/освобождений памяти.

Потом как правило объект StringBuilder находиться в методе, и сразу. умирает, то есть он вполне может использовать стек а не кучу

Нет, не может, тк размер финальной строки заранее не известен, а если очень много памяти на стеке выделять, то его просто порвёт.


Потом вообще почему любое new String (char[] ) копирует массив? почему не оборачивает

Потому что string имеет контракт "никогда и ни при каких условиях содержимое строки не будет изменено". Если просто оборачивать, то этот контракт легко будет нарушить.

А так да, можно и быстрее, если ты сможешь доказать, что ты никак не изменишь буфер, на котором основана строка после того, как можно будет использовать экземпляр string.

Например как в случае со string.Create где ты можешь прокинуть лямбду, котороя сможет как угодно менять содержимое строящейся строки.
string.Create выделяет память только один раз