2

私がやろうとしていることは少しハックであることは理解していますが、それでも興味深いものです。

配列に期待するほど多くのアイテムがない可能性が非常に高い状況にあります。

コンセプトは次のとおりです。

namespace TESTAPP
{
    class Program
    {
        static void Main(string[] args)
        {
            string derp = "foooooo";
            //The split is important, you might not have the character there to split by
            Writer(derp.Split('x')[0] ?? ".");
            Writer(derp.Split('x')[1] ?? ".");
        }

        private static void Writer(string writeme)
        {
            Console.WriteLine(writeme ?? "..");
        }
    }
}

当然のことながら、上記のプリントを実行してもあまり驚かない:

foooooo

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at TESTAPP.Program.Main(String[] args) in [snip]\TESTAPP\Program.cs:line 15

この状況を論理的にどのように扱うべきですか?try/catchブロックはやり過ぎのようです。

4

9 に答える 9

2

まず、すべての部分を再度分割するのではなく、一度だけ分割する必要があります。

string derp = "foooooo";
string[] parts = derp.Split('x');
// parts == { "foooooo" }
// parts.Length == 1

これで、多数のパーツを含む配列ができたので、Length各パーツにアクセスする前にプロパティを簡単に確認できます。

Writer(parts.Length > 0 ? parts[0] : ".");
Writer(parts.Length > 1 ? parts[1] : ".");
Writer(parts.Length > 2 ? parts[2] : ".");
Writer(parts.Length > 3 ? parts[3] : ".");
Writer(parts.Length > 4 ? parts[4] : ".");

また

for (int i = 0; i < 5; i++)
{
    Writer(parts.Length > i ? parts[i] : ".");
}

出力:

foooooo..
...
...
...
...
于 2013-07-02T10:09:16.817 に答える
1

この特定の例では..結果を繰り返し処理します。

foreach (var item in derp.Split('x'))
    Writer(item);

別の特定のケースがある場合..これは明らかに要件に合わない可能性があります。

于 2013-07-02T10:08:34.763 に答える
1

条件を適切に変更するだけで、すべてをインラインで記述しようとしないでください。

var split = derp.Split('x');
Writer(split.Length >= 2 ? split[1] : ".");

そのような条件がたくさんあり、入力に何も存在しない場合にそれぞれが異なる値にデフォルト設定される場合は、事前に配列のサイズを変更できます。

var split = derp.Split('x');
Array.Resize(ref split, 2);

Writer(split[1] ?? "."); // this is now safe

上記は[1]、その配列要素の内容について何も述べていないため、書かれているようには見えないことに注意してください。したがって、デフォルトが".".

于 2013-07-02T10:08:37.753 に答える
1

GetOrDefault次のように、拡張メソッドを定義します。

// If you need this method to work with collections or even IEnumerables,
// you can change implementation to get the count differently.
// This should be sufficient for arrays, though:
static T GetOrDefault(this T[] items, int index) {
    return items.Length > index ? items[index] : default(T);
}

これで、このメソッドを次のように使用できます。

Writer(derp.Split('x').GetOrDefault(0) ?? ".");
Writer(derp.Split('x').GetOrDefault(1) ?? ".");
于 2013-07-02T10:11:41.410 に答える
1

問題はderp.Split('x')[1].

[1] 要素が存在しないため、null かどうかを確認することはできません。状況を想像してみてください。バケツを 1 つ渡して、その中に「foooooo」を入れます。それでは、お願いします"Is the second bucket empty?"。言えない"yes"、言えない"no"。バケットが存在しないだけなので"ArrayIndexOutOfBoundsException"、2 番目のバケットがないため、空かどうかを確認できません ;)

于 2013-07-02T10:16:26.727 に答える
0

によって返された配列を反復処理します。Split

var splitOutput = derp.Split('x');

foreach (var s in splitOutput)
     Writer(s);
}
于 2013-07-02T10:08:48.117 に答える
0

分割統治。

値が存在すると予想される場合:

static void Main(string[] args)
{
    string derp = "foooooo";
    var parts = derp.Split('x');
    if (parts.Length != 2)
        throw new InvalidOperationException("Expected string to have to dot X delimited values. Actual string: " + derp);

    Writer(derp.Split('x')[0] ?? ".");
    Writer(derp.Split('x')[1] ?? ".");
}

値が欠落していることが予想される場合:

static void Main(string[] args)
{
    string derp = "foooooo";
    var parts = derp.Split('x');

    if (parts.Length > 0)
        Writer(parts[0]);
    else
        Writer(".");

    if (parts.Length > 1)
        Writer(parts[1]);
    else
        Writer(".");

}
于 2013-07-02T10:10:40.807 に答える
0

これが例外的な状況でない場合は、可能であれば例外を使用しないでください。

この具体的なケースでは、例外の使用を避け、次のような単純な境界制御のみを使用できます(単なる例):

var splitted = derp.Split('x');
if(splitted.Length > 1) {
   Writer(derp.Split('x')[0] ?? ".");
   Writer(derp.Split('x')[1] ?? ".");
}
于 2013-07-02T10:07:21.660 に答える
0

if次のステートメントを使用する必要があります。

var result = derp.Split('x');
if (result.Length > 0)
    Writer(result[0]);
else
    //...
于 2013-07-02T10:08:27.933 に答える