4

私のコードは、特定の入力に対して Index out of Range 例外を与えていました。以下は問題のあるコードです。

string[] snippetElements = magic_string.Split('^');

string a = snippetElements[10] == null ? "" : "hello";
string b = snippetElements[11] == null ? "" : "world";

その特定の入力について、配列 snippetElements には要素が 1 つしかないため、10 番目と 11 番目の要素にインデックスを付けようとすると、例外が発生しました。

今のところ、次のチェックを導入しました。

if (snippetElements.Length >= 11)
{
    string a = snippetElements[10] == null ? "" : "hello"; 
    string b = snippetElements[11] == null ? "" : "world";
}

誰かがこの小切手を書くためのより良い方法を提案できますか? どういうわけか、数字の 11 はコード内で見栄えがよくありません。

4

6 に答える 6

1

問題を次のような拡張メソッドに一般化できます。

public static class ArrayExtensions
{
    public static bool TryIndex<T>(this T[] array, int index, out T result)
    {
        index = Math.Abs(index);

        result = default(T);
        bool success = false;

        if (array != null && index < array.Length)
        {
            result = (T)array.GetValue(index);
            success = true;
        }

        return success;
    }
}

そして、コードを次のように変換します。

string[] snippetElements = magic_string.Split('^');

string a = null;
string b = null;

if (snippetElements.TryIndex(10, out a) && snippetElements.TryIndex(11, out b))
{
}

または、ソースコードのように、TryIndex(...)拡張メソッドを使用します。

string[] snippetElements = magic_string.Split('^');

string a = null;
string b = null;

snippetElements.TryIndex(10, out a);
snippetElements.TryIndex(11, out b);

a = a ?? "hello"; // Null coalesence ?? operator is great!
b = b ?? "world";

コードがスローすることはないため、配列のインデックス付きアクセスがより安全になりますArgumentOutOfRangeException

この拡張メソッドは、タイプに関係なく、あらゆる種類の配列で機能することに注意してください。値型(int、byte ...)または参照型(string、独自のクラス...)の場合。

于 2013-02-08T11:31:47.883 に答える
1

誰かがこの小切手を書くためのより良い方法を提案できますか? どういうわけか、数字の 11 はコード内で見栄えがよくありません。

インデックスを使用して要素にアクセスして11います。変数にそのインデックスがある場合は、チェックでそれを使用できます。そうでない場合11は、チェックで問題ありません。あなたの小切手はif(index < snippetElements.Length)

何かのようなもの:

int index = 11;

if(index < snippetElements.Length)
{
   string b = snippetElements[index] == null ? "" : "world";
}
于 2013-02-08T11:06:51.287 に答える
1

snippetElements[11]12番目の要素です。

if (snippetElements.Length >= 12)

実際に [10] および [11] インデックスを使用している限り、if ステートメントで 12 を使用しても問題はないようです。

于 2013-02-08T11:07:01.050 に答える
0

もう遅いかもしれませんが、同じ問題を抱えている他の人にとっては、それが私が解決した方法です. 通常、このロジックは for ループ内で使用します。

int index = 10;
string a = (index < snippetElements?.Length) ? snippetElements[index] : string.Empty; 

snippetElements?.LengthsnippetElements が空でないかどうかを確認し、その Length プロパティを呼び出します。空の配列の Length プロパティにアクセスすると、例外が発生します。 snippetElements[index](例のようにこれを「hello」に置き換えることができます)インデックスが配列の境界内にある場合にのみアクセスされます。それ以外の場合は、String.Empty を a に割り当てます。

于 2021-01-07T08:22:42.137 に答える
0

ここの論理は間違っています。Splitメソッドが生成する要素が 12 未満の場合、配列のインデックス付けは配列の
0から (Length - 1) までしかできません。snippetElements

その場合、インデックス 10 または 11 に要素はありません。また、いずれにせよ、snippetElement.Lenghtが 12 以上の場合、配列内の要素を null にすることはできません。または、文字列が含まれているか、空の文字列になります。
あなたはただ書くことができます

string a = snippetElements.Length >= 12 ? "hello" : string.Empty; 
string b = snippetElements.Length >= 12 ? "world" : string.Empty;
于 2013-02-08T11:13:26.780 に答える