String.Trim*(params ReadOnlySpan<char>) 오버로드가 제거됨
.NET 에코시스템에서 다음을 ReadOnlySpan<char>
나타낼 수 있습니다.
- 특정 문자 시퀀스(대개 큰 System.String 인스턴스의 조각)입니다.
- 단일 문자의 컬렉션으로, 종종 한 조각
char[]
으로 사용됩니다.
.NET 9의 이전 릴리스는 이미 오버로드가 있는 메서드 그룹에 오버로드를 params T[]
추가 params ReadOnlySpan<T>
했습니다. 이 오버로드는 일부 메서드 그룹에 대해 긍정적인 추가이지만 이중 특성 ReadOnlySpan<char>
으로 인해 a 및 a String (동일한 위치)를 수락 char[]
하고 다르게 처리되는 메서드 그룹에 혼동을 일으킬 수 있습니다. 예를 들어 public static string [String::]Split(string separator, StringSplitOptions options)
문자 시퀀스를 하나의 구분 기호로 간주합니다. 예를 들어 . "[]ne]-[Tw[]".Split("]-[", StringSplitOptions.None)
new string[] { "[]ne", "Tw[]" };
반면 public static [String::]Split(char[] separator, StringSplitOptions options)
에 각 문자를 separator
고유 구분 기호로 간주하므로 배열에 해당하는 분할이 생성됩니다 new string[] { "", "", "ne", "", "", "Tw", "", "" }
. 따라서 a ReadOnlySpan<char>
를 허용하는 새 오버로드는 문자열과 유사한지 또는 배열과 같은지 결정해야 합니다. 일반적으로 .NET은 배열과 유사한 동작을 준수합니다.
dotnet/runtime#77873에서 제안된 대로 인수를 수락 ReadOnlySpan<char>
하는 다음과 같은 새 String 오버로드를 고려합니다.
public string[] Split(params ReadOnlySpan<char> separator);
public string Trim(params ReadOnlySpan<char> trimChars);
public string TrimStart(params ReadOnlySpan<char> trimChars);
public string TrimEnd(params ReadOnlySpan<char> trimChars);
또한 다음과 같이 일반적으로 정의된 확장 메서드를 고려합니다.
public static class SomeExtensions {
public static string TrimEnd(this string target, string trimString) {
if (target.EndsWith(trimString) {
return target.Substring(0, target.Length - trimString.Length);
}
return target;
}
}
기존 .NET 런타임의 경우 이 확장 메서드는 문자열의 끝에서 지정된 시퀀스를 제거합니다. 그러나 C# "12345!!!!".TrimEnd("!!!")
의 오버로드 확인 규칙으로 인해 기존 확장 메서드에 대한 새 TrimEnd
오버로드를 선호하고 결과를 "12345!"
변경합니다(세 개의 느낌표의 전체 집합만 제거) "12345"
에서 (끝에서 모든 느낌표 제거).
이 중단을 해결하기 위해 두 가지 가능한 경로가 있었습니다. 더 나은 대상인 인스턴스 메서드 public string TrimEnd(string trimString)
를 도입하거나 새 메서드를 제거합니다. 첫 번째 옵션은 대상 문자열의 인스턴스 하나 또는 모두를 반환할지 여부를 결정해야 하므로 추가 위험을 수반합니다. 또한 각 접근 방식을 사용하는 기존 코드를 사용하는 호출자가 의심할 여지 없이 있습니다. 따라서 두 번째 옵션은 릴리스 주기의 이 단계에 가장 적합한 선택이었습니다.
예를 들어 str.Trim(';', ',', '.')
기능을 사용하여 params
개별 문자를 전달하는 호출자에게 String.Trim 는 중단이 표시되지 않습니다. 코드가 자동으로 호출 string.Trim(params char[])
string.Trim(params ReadOnlySpan<char>)
에서 .로 전환됩니다. .NET 9의 GA 릴리스에 대해 다시 빌드하면 컴파일러가 자동으로 오버로드로 char[]
다시 전환됩니다.
명시적으로 전달 ReadOnlySpan<char>
한 호출자String.Trim(또는 변환char[]
할 수 ReadOnlySpan<char>
없는 형식)는 이 변경 후 성공적으로 호출 Trim
되도록 코드를 변경해야 합니다.
String.Split와 달리 String.Trim이 메서드에는 이미 단일 문자열 매개 변수와 새로 추가 ReadOnlySpan<char>
된 오버로드를 허용하는 확장 메서드보다 기본 설정되는 오버로드가 있습니다. 이러한 이유로 새 오버로드가 String.Split 유지되었습니다.
참고 항목
제거된 메서드에 대한 호출이 제거되도록 .NET 9 Preview 6, .NET 9 Preview 7, .NET 9 RC1 또는 .NET 9 RC2에 대해 빌드된 어셈블리를 다시 빌드해야 합니다. 이렇게 하지 않으면 런타임에 MissingMethodException 발생할 수 있습니다.
도입된 버전
.NET 9 GA
이전 동작
.NET 9 Preview 6, .NET 9 Preview 7, .NET 9 RC1 및 .NET 9 RC2에서 컴파일된 다음 코드는 다음과 같습니다.
private static readonly char[] s_allowedWhitespace = { ' ', '\t', '\u00A0', '\u2000' };
// Only remove the ASCII whitespace.
str = str.Trim(s_allowedWhitespace.AsSpan(0, 2));
.NET 9 미리 보기 6 이전에는 다음 코드가 생성되었습니다 "prefixinfix"
. .NET 9 Preview 6~ .NET 9 RC2의 경우 대신 다음을 생성했습니다 "prefixin"
.
internal static string TrimEnd(this string target, string suffix)
{
if (target.EndsWith(suffix))
{
return target.Substring(0, target.Length - suffix.Length);
}
return target;
}
...
return "prefixinfixsuffix".TrimEnd("suffix");
새 동작
배열 조각을 명시적으로 사용하는 다음 코드는 호출하기에 적합한 오버로드가 없으므로 더 이상 컴파일되지 않습니다.
private static readonly char[] s_allowedWhitespace = { ' ', '\t', '\u00A0', '\u2000' };
// Only remove the ASCII whitespace.
str = str.Trim(s_allowedWhitespace.AsSpan(0, 2));
확장 메서드 string TrimEnd(this string target, this string suffix)
를 특징으로 하는 코드는 이제 .NET 8 및 이전 버전에서와 동일한 동작을 했습니다. 즉, 생성됩니다 "prefixinfix"
.
호환성이 손상되는 변경의 형식
이 변경은 이진 호환성 및 소스 호환성에 영향을 줄 수 있습니다.
변경 이유
많은 프로젝트에는 다시 컴파일한 후 동작이 변경되는 확장 메서드가 있습니다. 이러한 새 인스턴스 메서드의 부정적인 영향은 긍정적인 이점을 능가하는 것으로 간주되었습니다.
권장 조치
.NET 9 Preview 6, .NET 9 Preview 7, .NET 9 RC1 또는 .NET 9 RC2에 대해 빌드된 모든 프로젝트를 다시 컴파일합니다. 프로젝트가 오류 없이 컴파일되는 경우 추가 작업이 필요하지 않습니다. 프로젝트가 더 이상 컴파일되지 않으면 코드를 조정합니다. 가능한 대체 예제 중 하나는 다음과 같습니다.
-private static ReadOnlySpan<char> s_trimChars = [ ';', ',', '.' ];
+private static readonly char[] s_trimChars = [ ';', ',', '.' ];
...
return input.Trim(s_trimChars);
영향을 받는 API
System.String.Trim(System.ReadOnlySpan{System.Char})
System.String.TrimEnd(System.ReadOnlySpan{System.Char})
System.String.TrimStart(System.ReadOnlySpan{System.Char})
.NET