1

リストを持つクラスがあり、別のクラス メソッドでアクセスしています。それは正常に機能しますが、リストを do ループで使用しようとすると、常に「ArgumentOutOfRangeExcetpion」が発生します。リストをdoループ内で使用すると空になる理由、または少なくともそれが起こっていると思う理由を本当に混乱させています。なぜこれが起こっているのか誰かが私に説明できれば、それは非常に啓発的であり、おそらく私はこれを機能させる方法を理解できるでしょう.

これが私の方法です:

private void ListToAttributes()
    {
        int count = -1;

        //Finds Attribute starting Line.
        do
        {
            count = count + 1;

        } while (Player.PlayerList[count] != "Attributes;");

        //Adds all Attributes to a list
        List<string> TypeAndAmount = new List<string>();

        do
        {
            TypeAndAmount.Add(Player.PlayerList[count]);
            count = count + 1;
        } while (Player.PlayerList[count] != ".");

        //Sorts by type and adds amount to Player Class


        foreach (string Line in TypeAndAmount)
        {
            string[] Type = Line.Split(' ');

            if (Type[0] == "Mind") { Player.Mind = int.Parse(Type[1]); }
            if (Type[0] == "Body") { Player.Body = int.Parse(Type[1]); }
            if (Type[0] == "Soul") { Player.Soul = int.Parse(Type[1]); }
        }
    }
4

4 に答える 4

3

最初のループはArgumentOutOfRangeException、リスト内の項目が文字列と一致しない場合に発生します。この場合、喜んでリストの最後を通り過ぎます。2 番目のループにも同じ問題があります。

countさらに、2 つのループの間にもう 1 回インクリメントする必要があると思います。現在、項目"Attributes;"をリストに追加していますTypeAndAmountArgumentOutOfRangeExceptionスペースで文字列を分割すると文字列が 1 つしか生成されず、最後のループで"Attributes;"アクセスしているため、これも原因になります。Type[1]

LINQ を使用してコードを書き直すことをお勧めします (アイテムをスキップする手順を含む"Attributes;")。

// Skip everything until we find 'Attributes;'.
var stepOne = Player.PlayerList.SkipWhile(entry => entry != "Attributes;");

// Skip over 'Attributes;'.
var stepTwo = stepOne.Skip(1);

// Take everything until we find '.'.
var stepThree = stepTwo.TakeWhile(entry => entry != ".");

// Stuff everything we selected into a new list.
var typeAndAmount = stepThree.ToList();

すべてを 1 つのステートメントに入れることもできます。冗長ではありませんが、デバッグが難しくなります。

var typeAndAmount = Player.PlayerList
                          .SkipWhile(entry => entry != "Attributes;")
                          .Skip(1)
                          .TakeWhile(entry => entry != ".")
                          .ToList();
于 2012-12-18T18:49:21.847 に答える
1

最善の推測に基づいて回答を修正しています。2 番目の do ループをヒットすると、 Player.PlayerList[count] は引き続き「属性」と等しくなります。次に、2 番目のループに入り、「Attributes」を TypeAndAmount に追加します。その行で Line.Split(' ') を試すと、1 つの項目を含む配列のみが返されます。Type[1] は ArgumentOutOfRangeException をスローします。

2 番目の do ループの前に count = count +1 を追加すると、問題が解決すると思います。

最初の「属性」セクションを見つけるもう 1 つの賢い (私が思うに) 方法は、すべてを 1 行で囲むことです。

int count = -1;
while (Player.PlayerList[count++] != "Attributes;");

++ 表記は、count = count + 1 をより簡単に記述する方法です。これが役立つことを願っています。:)

于 2012-12-18T18:45:56.910 に答える
1

例外の原因となっている可能性のある問題がいくつか見られます。最初のループでは、配列が空でないことをチェックして確認する必要があります。また、「属性」が存在しない場合に備えて、配列のサイズをチェックする条件が必要です。多分試してください:

if (Player.PlayerList.Length > 0){
  do
  {
    count = count + 1;
  }while (count < Player.PlayerList.Length && Player.PlayerList[count] != "Attributes;");

Attributes が見つからない場合は、おそらく独自の例外をスローする必要があることに注意してください。2 番目のループでは、同様の条件を追加する必要があります。

if (count < Player.PlayerList.Length){
  do
  {
      TypeAndAmount.Add(Player.PlayerList[count]);
      count = count + 1;
  } while (count < Player.PlayerList.Length && Player.PlayerList[count] != ".");
}

これらは例外を防ぐだけであることに注意してください。このメソッドが期待するようにリストがレイアウトされていない場合でも、問題が発生します。

于 2012-12-18T19:09:01.877 に答える
0

問題は Do ループにあります。count を 1 増やしてから評価されます。これにより、カウントが要素の数よりも大きくなります。

これはうまくいきます:

 while (count < Player.PlayerList.Count && Player.PlayerList[count] != "Attributes;");
于 2012-12-18T18:46:50.650 に答える