이렇게 코드를 수정함으로써 코드가 좀 더 안전하게 바뀌긴 했지만 성능이 좋아진 것은 아니다. 데이터 복사 과정은 여전히 동일하게 수행되고 있기 때문이다. 좀 더 개선해 보자. System.String 내에 포함되어 있는 팩토리 메서드를 활용하기만 하면 된다.
public static string Create<TState>(
int length, TState state, SpanAction<char, TState> action)
이 메서드는 SpanAction<T, TArg>라는 델리게이트를 사용한다.
delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg);
이 두 개의 원형은 처음에는 다소 이상해 보일 수 있다. 우선 Create 메서드가 어떻게 구현되었는지 자세히 살펴보자. Create 메서드는 다음과 같이 수행된다.
1. 필요한 길이만큼 문자열을 할당한다.
2. 문자열이 저장될 메모리를 참조하는 스팬을 생성한다.
3. 앞서 생성한 스팬과 이 메서드에 주어진 state 정보를 인수로 action 델리게이트를 호출한다.
4. 문자열을 반환한다.
우선 이 과정에서 우리가 주목해야 할 부분은 문자열의 내용을 직접 쓸 수 있다는 점이다. 이는 문자열이 변경 불가능한 타입이라는 점을 무시하는 것처럼 들리지만, Create 메서드를 이용하면 이러한 작업을 수행할 수 있다. 마치 우리가 원하는 내용을 담은 문자열을 새롭게 생성하는 것처럼 문자열의 내용을 원하는 대로 쓸 수 있다는 이야기다. 문자열이 반환되는 시점이 되면, 이렇게 쓰여진 내용을 문자열 내부에 포함시킨다. 델리게이트에 전달한 Span<char>를 교묘하게 이용하면 무엇인가 부적절한 작업을 할 수 있을 것 같지만, 컴파일러 차원에서 Span<char>가 스택을 벗어나지 못하도록 제약을 가하기 때문에 그런 일은 일어나지 않는다.