web-dev-qa-db-ja.com

直感的でないC#String.Split()実装の背後にある理由

C#では、stringを別のstringで分割したい場合は、次のようにする必要があります。

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

過負荷から String.Split MSDNのドキュメントでは、実装とそのような呼び出しを行う必要がある理由を確認できます。

Pythonから来ているので、そのような呼び出しが必要な理由を正確に理解するのは難しいです。 Regex.Split Pythonの実装と同様の構文を取得するには、パフォーマンス(セットアップ時間)を犠牲にして実行する必要がありますsimple

基本的に、私の質問はなぜ地獄が私たちだけではできないのですか?

testString.Split("anotherString");

プロトタイプも実装も提案していないことに注意してください。現在のAPIを考慮して上記のバージョンを実装できなかった理由を理解しました。私の目標は、上記の構文がもたらす利点を考慮して、このようなAPIが作成された理由を理解することでした。今のところ、flexibilityが現在の目標であるようです String.Split これは理にかなっていますが、正直に言うと、どこかにパフォーマンスの向上があると思っていました。私は間違っていたと思います。

10
scharette

複数の文字/文字列で分割すると便利な場合があるため、APIを使用すると配列を提供できるため、最大限の柔軟性が得られます。 charsの場合、パラメーターがparamsとしてマークされているため、構文の単純さと柔軟性の両方が得られ、Split('x')ではなくSplit(new[]{'x'})と記述できます。

それでは、なぜ文字列に同様のオプションがなく、Split("x")と書けるのでしょうか?

これはおそらく、APIの設計方法の不幸な結果です。最初は、charの分割のみを許可していました。文字列の分割は2.0で追加されました。おそらく実装がより複雑だからです。ただし、String.Split(string)またはString.Split(string[])オーバーロードを追加することはできませんでした。これにより、式testString.Split(null)が曖昧になり、このコードはコンパイルできなくなります。

testString.Split(null)は文字列を空白で分割するため、実際にはかなり一般的なイディオムです。そのため、このような破損は広範囲に及ぶため、許容できません。

最近、nullパラメータを特別な動作のスイッチとして使用することは、一般に設計が悪いと考えられているため、このAPIに欠陥があると言っても差し支えないと思います。

Split(string[], Int32)もありませんが、おそらく同様の理由で、最初のパラメーターがnullである場合、Split(char[], Int32)があいまいになります。そこにareStringSplitOptionsパラメータを持つ同様のオーバーロードがありますが、これらは2.0で同時に追加されたので、あいまいさは導入されていません既存のコード。

明確にするために、これは私の仮説にすぎず、.netフレームワークのデザイナーによる実際の考え方はわかりません。

15
JacquesB

メソッドの作成者ではないため、そのオーバーロードのセットが選択された理由がわかりません。ただし、ここで2つの注意点があります。

  1. 単一の文字で分割する場合は、_public string[] Split(params char[] separator_)バージョンを使用できます。

    _var splitValues = testString.Split(',');
    _

    _char[]_は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");が動作します。

2
David Arno

言語によって、暗黙の変換とオーバーロードに関するルールが多少異なります。NETFrameworkは、それらのいずれでも使用できるように設計されています。 VB.NETの_Option Strict Off_方言では、String型の値は、ToCharArray()を呼び出すのと同等の動作で_Char[]_を期待する関数に渡される場合があります。文字列。

私がすべき賢明なことは、Split(単一のCharまたはStringを受け入れる)とSplitMulti(これは_Char[]_または_String[]_)を受け入れますが、.NETは、オーバーロードのみを使用してさまざまな種類の操作を選択することを好むようです。残念ながら、_String.Split_を使用して、区切り文字を個別に区別する以外に、さまざまな種類の区切り文字を区別する必要がある使用シナリオに対応する方法はありません。

別の省略は、前の文字列の末尾または次の文字列の先頭に区切り文字を含めるか、奇数番号の配列要素を区切り文字として使用し、偶数番号の要素がそれらの間の区切り文字を保持するオプションです。

1
supercat