직관적이지 않은 C # String.Split () 구현의 이유


10

C # string에서 다른 것으로 나누려면 string다음과 같이해야합니다.

testString.Split(new string[] { "anotherString" }, StringSplitOptions.None);

오버로드 된 String.SplitMSDN Documentation에서 구현과 호출이 필요한 이유를 확인할 수 있습니다.

파이썬 에서 왔을 때 , 왜 그러한 호출이 필요한지 올바르게 이해하기가 어렵습니다. 필자 Regex.Split는 파이썬 구현과 비슷한 구문을 얻는 데 사용할 수 있지만 간단한 작업 을 위해서는 성능 (설정 시간)을 낮추어 비용을 지불해야합니다 .

그래서 기본적으로 내 질문은 왜 우리가 할 수 없는지입니다.

testString.Split("anotherString");

프로토 타입이나 구현을 제안하지는 않습니다. 현재 API를 고려하여 위 버전을 구현할 수없는 이유를 이해합니다. 저의 목표는 위의 구문이주는 이점을 고려하여 왜 그러한 API가 만들어 졌는지 이해하는 것이 었습니다. 현재로서는 유연성 이 현재의 목표 인 것처럼 보이지만 String.Split솔직히 말하면 어딘가에 일종의 성능 향상이 있다고 생각했습니다. 내가 틀렸다고 생각한다.


3
나도 이것에 대해 생각하고 있었다. 내 생각에 그들은이 하나의 API를 디자인하는 데 많은 노력을 기울이지 않았다는 것입니다. 그리고 그들이 실수를 깨달았다면 너무 늦었습니다.
Euphoric

@Caleth 이것에 대해 자세히 설명해 주시겠습니까? 어쩌면 내가 틀렸지 만 그것에 대해 모호한 것이 보이지 않습니다. 이유는 할 수 없습니다 testString.Split(",.;");testString.Split(new Char [] {',', '.', ';',);같은 것이 아니다한다.
scharette

@Euphoric 나도 그렇게 힘들지만, 너무 이상합니다. 누군가 더 논리적 인 답변을 제공하기를 바랍니다.
scharette

IEnumerable<char>제안한 추가 프로토 타입이 특정 경우 모호하게 나타날 수 있도록 문자열을 반복 할 수 있습니다 (전체 문자열로 구분하거나 각 문자로 구분합니까?).
John Wu

@JohnWu 아마도 개인적인 일 일 것입니다. 그러나 99.9 %와 같은 구문의 경우 testString.Split("anotherString");예상되는 동작이 전체 문자열 ( anotherString이 경우) 을 구분하는 것이라고 확신합니다 .
scharette

답변:


15

때로는 둘 이상의 문자 / 문자열로 분할하는 것이 유용하므로 API를 사용하면 배열을 제공하여 최대한의 유연성을 제공 할 수 있습니다. 의 경우 char매개 변수가로 표시되어 대신 params작성할 수 있으므로 구문의 단순화와 유연성이 모두 확보 됩니다.Split('x')Split(new[]{'x'})

그렇다면 문자열에 비슷한 옵션이없는 이유는 Split("x")무엇입니까?

이것은 아마도 API 디자인 방식의 불행한 결과 일 것입니다. 처음에는 문자 분리 만 허용했습니다. 구현이 더 복잡하기 때문에 문자열 분할이 2.0에 추가되었습니다. 그러나 표현식을 모호하게 만들고이 코드는 더 이상 컴파일되지 않기 때문에 추가 String.Split(string)하거나 String.Split(string[])오버로드 할 수 testString.Split(null)없습니다.

testString.Split(null) 실제로 문자열을 공백으로 나누기 때문에 꽤 일반적인 관용구이므로 그러한 파손은 너무 광범위하여 수용 할 수 없습니다.

null요즘에는 특수한 동작을위한 스위치로 -parameter를 사용하는 것이 좋지 않은 디자인으로 간주되므로이 API에 결함이 있다고 말하는 것이 공정하다고 생각합니다.

Split(string[], Int32)아마도 비슷한 이유로 아마도 없습니다 - Split(char[], Int32)첫 번째 매개 변수가 인 경우 모호합니다 null. 이 있습니다 와 유사한 과부하 StringSplitOptions매개 변수가 있지만 모호성이 기존 코드에 도입되지 않았다 그래서이 모든, 2.0 동시에 추가되었다.

노트

분명히, 이것은 내 가설에 불과합니다 .NET Framework 디자이너의 실제 사고를 모르겠습니다.


1
글쎄, 그게 유용한가요? 의심합니다. 그리고 ABI가 아닌 API 중단 일뿐입니다.
중복 제거기

2
@Deduplicator : Split (null)은 공백으로 분할되므로 이와 같은 null을 사용하는 API 디자인이 좋지 않더라도 split의 가장 일반적인 사용 사례 중 하나 일 수 있습니다.
JacquesB

1
@Deduplicator가 Split(null)허용하면 쓸모가 없다고 말하고 싶었습니다 Split(""). 그것이 더 나은 구문을 허용 할 것이라는 사실 외에, 후자는 어쨌든 더 장황하다 ...
scharette

1
@ scharette : 물론입니다. 그러나 이전 버전과의 호환성을 유지하지 않으면 서 지금 변경할 수 없습니다.
JacquesB

1
참고 : 현재 C # 8 미리보기에서 기본 유형의 널 입력 기능을 해제 String.Split(null)해도 더 이상 모호하지 않으므로 과부하를 추가 할 수 있습니다.
BgrWorker

2

메소드 작성자가 아니기 때문에 해당 과부하 세트가 선택된 이유를 모르겠습니다. 그러나 여기에 두 가지주의 할 사항이 있습니다.

  1. 단일 문자로 분할하는 경우 public string[] Split(params char[] separator) 버전을 사용할 수 있습니다.

    var splitValues = testString.Split(',');

    같이 char[]A는 params파라미터.

  2. 여기에 원하는 확장 방법을 쉽게 추가하여 원하는 것을 얻을 수 있습니다.

    public static class StringExtensions
    {
        public static string[] Split(this string source, string separator)
            => source.Split(new string[] { separator }, StringSplitOptions.None);
    }

    지금 testString.Split("anotherString");당신을 위해 일할 것입니다.


1
피드백을 주셔서 감사합니다. 답변이 도움이되고 간결하지만 동의하지 않습니다. 특히 두 번째 요점. 내장해야 할 이유가 하나 더 없습니까? 모든 것은 (또는 거의 모든 사람이) 같은 방식으로 행동 할 것으로 기대되는 다른 버전의 방법을 커뮤니티가 만들도록하는 것입니다.
scharette

그건 그렇고 논쟁을하지 않으려는 요점은 전적으로 유효합니다. 이것의 이유를 이해하려고합니다. 논리적으로 역사적 또는 성능상의 이유가 있어야합니다 ...
scharette

@ scharette : 이유는 가능한 한 일반적인 방법을 사용하는 것입니다. 선택한 메소드 서명을 찾으면 여러 구분 기호에 대해 작동하지 않습니다. Microsoft 버전은 단일 구분 기호뿐만 아니라 여러 구분 기호에도 사용할 수 있습니다.
Robert Harvey

@RobertHarvey 둘 다 가능하지 않습니까? 위의 답변에서 확장 방법이 String클래스의 일부라고 가정 해 보겠습니다 . 내가 잘못 ?
scharette

나는 당신이 요점을 놓치고 있다고 생각합니다. 과부하는 하나의 분리 문자 만 허용합니다. Microsoft의 과부하는 둘 이상을 허용합니다. 오버로드를 여러 번 호출하여 동일한 결과를 얻을 수는 없습니다. 이것이 작동하는 방식이 아닙니다.
Robert Harvey

1

언어마다 암시 적 변환 및 오버로드에 대해 약간 다른 규칙이 있으며 .NET Framework는 모든 언어에서 사용할 수 있도록 설계되었습니다. Option Strict OffVB.NET 의 방언에서 type 값은 문자열 을 호출 하는 것과 동일한 동작 String을 기대하는 함수에 전달 될 수 있습니다 .Char[]ToCharArray()

내가 할 수있는 합리적인 것은 별도의 이름을 가지고 있었을 것이다 생각 Split(단일 수락 Char또는 String과) SplitMulti(A 동의 것이다 Char[]또는 String[]), 그러나 .NET 때로는 작업의 종류를 선택하기 만 오버로드를 사용하여 선호하는 것 같다. 불행히도, 나는 String.Split각각에 대해 별도로 분리하는 것 이외의 다른 종류의 구분자를 구별 해야하는 사용 시나리오를 수용하는 데 사용할 방법을 알지 못합니다 .

또 다른 생략은 선행 문자열의 끝 또는 다음 문자열의 시작 부분에 포함하거나 분리 번호를 갖는 요소를 구분 기호로 포함하고 짝수 번호의 요소가 그들 사이에있는 구분 기호를 유지하는 옵션입니다.


1
.NET은 때로는 다른 종류의 작업을 선택하기 위해 오버로드 만 사용하는 것을 선호합니다. 그러니까 ...
scharette
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.