演習 - 新しいペット データを入力するためのループを構築してテストする
この演習では、新しい ourAnimals 配列データの入力を制御するコードを開発します。 ループ制御変数の初期値を計算し、動物のユーザー指定データを収集するループを構築します。 この演習で完了する詳細なタスクは次のとおりです。
- petCount を計算する: データが割り当てられている
ourAnimals配列内のペットの数をカウントするコードを記述します。 - 条件付きメッセージ:
petCountがmaxPets未満の場合にメッセージ出力を表示するコードを記述します。 - 外側のループ: 新しい
ourAnimals配列データを入力するために使用されるループ構造を構築します。 - 終了条件: "新しい ourAnimals 配列データの入力" ループの終了条件を評価するコードを記述します。
- 検証テスト: この演習で開発したコードの検証テストを実行します。
重要
この演習を開始する前に、このモジュールの前の演習を完了する必要があります。
ourAnimals 配列内のペットの数をカウントする
このタスクでは、データ入力ループの終了条件を設定し、データが割り当てられているforのペットの数をカウントするために使用できるourAnimals ループを作成します。
Visual Studio Code が開き、Program.cs ファイルがエディターに表示されていることを確認します。
switch(menuSelection)ステートメントを見つけて、case "2":コード行を見つけます。"近日公開予定" メッセージを表示する
Console.WriteLine()ステートメントを見つけて、空白のコード行に置き換えます。作成した空白のコード行で、
anotherPet変数とpetCount変数を宣言するには、次のコードを入力します。string anotherPet = "y"; int petCount = 0;これら 2 つの変数は、新しいペット データの入力に使用される
whileループの反復を制御します。 両方の変数を宣言の一部として初期化します。anotherPetは、yループの開始前にwhileの値で初期化されます。yループ内でユーザー割り当て値 (nまたはwhile) を受け取ります。petCountは、ペットの特性が割り当てられた動物の数を表します。whileループの外部に計算値が割り当てられ、新しい動物が1配列に追加されるたびに、whileループ内のourAnimalsずつインクリメントされます。
重要
変数のスコープは、常にできるだけ狭くする必要があります。 Contoso Pets アプリケーションでは、
petCountコード ブロックにスコープを設定するのではなく、アプリケーション レベルでcase "2":スコープを設定できます。 スコープが大きいほど、アプリケーション内のどこからでもpetCountにアクセスできます。petCountアプリケーション レベルでスコープが設定されている場合は、サンプル データを作成するときに値を割り当て、アプリケーションの残りの部分でその値をプログラムで管理できます。 たとえば、ペットの家を見つけてourAnimals配列からペットを削除すると、petCountで1を減らすことができます。 問題は、アプリケーションの他の部分で変数が使用されるかどうかわからないときに、どのレベルで変数のスコープを設定する必要があるかです。 この場合、他の場所で使用していない場合でも、アプリケーション レベルでpetCountのスコープを設定するのは魅力的です。 結局のところ、アプリケーション レベルでpetCountスコープを設定すると、他の場所で使用する場合に使用できるようになります。 アプリケーション レベルで他の変数のスコープを設定することもできます。 そうすることで、変数は常にスコープ内にあり、アクセス可能になります。 では、後でアプリケーションで使用される可能性があると思われるときに、アプリケーション レベルで変数のスコープを設定してみませんか? 必要以上に高いレベルで変数をスコープすると、問題が発生する可能性があります。 昇格されたスコープにより、アプリケーションのリソース要件が増大し、アプリケーションが不要なセキュリティ リスクにさらされる可能性があります。 アプリケーションの規模が大きくなり、複雑になるにつれて、より多くのリソースが必要になります。 電話とコンピューターは、スコープ内にあるときにこれらのリソースのメモリを割り当てます。 アプリケーションの "現実世界" が増えるにつれて、アプリケーションのアクセシビリティが高くなります。 多くの場合、アプリケーションはクラウドや他のアプリケーションからアクセスできます。 これらの問題を複合化すると、多くの場合、アプリケーションは使用されていないときに実行したままになります。 アプリケーションのリソース要件を制御し、セキュリティフットプリントを可能な限り小さくすることが重要です。 現在のオペレーティング システムは、リソースを管理し、アプリケーションをセキュリティで保護する優れた仕事をしていますが、変数を実際に必要なレベルに範囲指定しておくことをお勧めします。 Contoso Pets アプリでアプリケーション内でより広くpetCountを使用することを決定した場合、より高いレベルでスコープをpetCountするようにコードを更新できます。 変数のスコープはできるだけ狭くし、必要になったときにのみスコープを広げることを忘れないでください。変数宣言の下のコード行で、
ourAnimals配列内の動物を反復処理するループを作成するには、次のコードを入力します。for (int i = 0; i < maxPets; i++) { }このコードは使い慣れているはずです。 この
forループは、ourAnimals配列を反復処理するたびに使用します。forループのコード ブロック内で、ペットの特性データが動物に割り当てられているかどうかを確認するには、次のコードを入力します。if (ourAnimals[i, 0] != "ID #: ") { }ここでも、このコードは使い慣れているはずです。 この
ifステートメントは、ペットの特性が割り当てられているかどうかを確認するたびに使用します。作成した
ifのコード ブロック内で、petCountを 1 ずつインクリメントするには、次のコードを入力します。petCount += 1;完了した
forループを調べるには 1 分かかります。完了した
forループは、次のコードのようになります。for (int i = 0; i < maxPets; i++) { if (ourAnimals[i, 0] != "ID #: ") { petCount += 1; } }このコードは、割り当てられたデータをチェックする
ourAnimals配列をループ処理します。 データが割り当てられている動物が見つかると、petCounter増加します。Visual Studio Code の [ファイル] メニューで、[保存] を選択します。
Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。
エクスプローラー ビューから統合ターミナルを開くには、[ スタート] を右クリックし、[ 統合ターミナルで開く] を選択します。 [ 表示 ] メニューまたは [ターミナル ] メニューを使用して、[統合ターミナル] パネルを開くこともできます。
プログラムをビルドするには、ターミナル コマンド プロンプトから
dotnet buildコマンドを入力します。続行する前に報告されたビルド エラーを修正します。
注
現時点では、割り当てられているが使用されていない
anotherPetに関する警告メッセージは無視できます。 この演習の後半で、anotherPetを使用するコードを追加します。ビルド エラーがある場合は、ビルド エラーと警告メッセージに、問題の内容と見つかる場所が示されていることに注意してください。 コードを更新する場合は、リビルドする前に必ず変更を保存してください。
[ターミナル] パネルを閉じます。
petCount が maxPets 未満の場合にメッセージ出力を表示する
このタスクでは、 petCount が maxPets 未満かどうかを確認し、その場合はユーザーのメッセージを表示します。
作成した
forループの下の空白のコード行で、petCountがmaxPets未満かどうかを確認するには、次のコードを入力します。if (petCount < maxPets) { }ifステートメントのコード ブロック内で、ユーザーにメッセージを表示するには、次のコードを入力します。Console.WriteLine($"We currently have {petCount} pets that need homes. We can manage {(maxPets - petCount)} more.");アプリケーション ユーザーは、ペットの特性を入力します。 このメッセージは、重要なコンテキストを提供します。
少し時間を取って、
case "2":ステートメントのswitchコード ブランチを確認してください。この時点で、
case "2":コード ブランチは次のコードのようになります。case "2": // Add a new animal friend to the ourAnimals array string anotherPet = "y"; int petCount = 0; for (int i = 0; i < maxPets; i++) { if (ourAnimals[i, 0] != "ID #: ") { petCount += 1; } } if (petCount < maxPets) { Console.WriteLine($"We currently have {petCount} pets that need homes. We can manage {(maxPets - petCount)} more."); } Console.WriteLine("Press the Enter key to continue."); readResult = Console.ReadLine(); break;Visual Studio Code の [ファイル] メニューで、[保存] を選択します。
Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。
続行する前に報告されたビルド エラーを修正します。
ここでも、割り当てられているが使用されていない
anotherPetに関する警告メッセージは無視できます。 次のタスクでは、1 つ以上のペットのデータを入力するために使用するwhileループの構築を開始します。whileループ用に作成した式では、anotherPetが使用され、この警告メッセージは表示されなくなります。警告メッセージは懸念すべき事柄ですが、プログラムの実行を妨げることはありません。
ターミナルのコマンド プロンプトで、プログラムを実行するコマンドを入力します。
ターミナル コマンド プロンプトで
dotnet runコマンドを入力して、プログラム コードを実行します。コードでランタイム エラーが生成されない限り、アプリのメイン メニューがターミナル パネルに表示されます。
ターミナルのコマンド プロンプトで、「2」と入力します。
この値は、
case "2":コード ブランチに対応します。ターミナルに次のメッセージが表示されていることを確認します。
We currently have 4 pets that need homes. We can manage 4 more. Press the Enter key to continue.予想されるメッセージが表示されない場合は、コードを確認して問題を特定して修正します。 変更を保存し、再構築して、アプリをもう一度実行します。 続行する前に、コードを期待どおりに動作するようにしてください。
ターミナル コマンド プロンプトで Enter キーを押して、アプリケーションの実行を続行します。
アプリケーションを終了し、ターミナル パネルを閉じます。
新しい ourAnimals 配列データの入力に使用されるループ構造を構築する
このタスクでは、whileがanotherPetに等しく、yがpetCount未満である限り、反復処理を継続するmaxPets ループを作成します。
コード エディターで、
if (petCount < maxPets)コード ブロックの下に空白のコード行を作成します。新しい
whileループを作成するプロセスを開始するには、次のコードを入力します。while (anotherPet == "y" && petCount < maxPets) { }Visual Studio Code の [ファイル] メニューで、[保存] を選択します。
Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。
使用されていない
anotherPetに関する警告メッセージが表示されなくなったことに注意してください。ビルド エラーまたは警告が報告された場合は、続行する前に問題を修正してください。
新しいペット ループの終了条件を調べる
このタスクでは、 while (anotherPet == "y" && petCount < maxPets) コード ブロックを更新します。 新しいコードは petCount インクリメントされ、 petCount が maxPets未満かどうかを確認します。
petCountがmaxPets未満の場合は、別のペットの情報を入力するかどうかをユーザーに確認し、応答がyまたはnであることを確認します。
while (anotherPet == "y" && petCount < maxPets)コード ブロックの後に、petCountの値を確認します。
petCountがmaxPetsと等しい場合は、ペットを追加できないことをユーザーに通知します。
注
ペットデータの入力に使用されるコードは、次の演習で開発されます。 現時点では、データが入力され、petCount配列に保存されているかのように、ourAnimalsがインクリメントされます。 これにより、 while ループに関連付けられているコード ロジックの開発を完了できます。
前のタスクで作成した
while (anotherPet == "y" && petCount < maxPets)ループのコード ブロック内に空白のコード行を作成します。petCountをインクリメントするには、次のコードを入力します。// increment petCount (the array is zero-based, so we increment the counter after adding to the array) petCount = petCount + 1;petCountがmaxPets未満かどうかを確認するには、次のコードを入力します。// check maxPet limit if (petCount < maxPets) { }作成した
ifステートメントのコード ブロック内で、別のペットを追加するかどうかをユーザーに確認するには、次のコードを入力します。// another pet? Console.WriteLine("Do you want to enter info for another pet (y/n)");入力した
WriteLine()メッセージの下で、ユーザーの応答を読み取り、ユーザーが "y" または "n" と入力したことを確認するには、次のコードを入力します。do { readResult = Console.ReadLine(); if (readResult != null) { anotherPet = readResult.ToLower(); } } while (anotherPet != "y" && anotherPet != "n");breakステートメントでcase "2";とcase "3";を分離するswitchステートメントを見つけます。Console.WriteLine()コードの末尾にあるConsole.ReadLine()ステートメントとcase "2";ステートメントに注目してください。このコードは、ユーザーにメッセージを表示し、アプリケーションを一時停止します。
Console.WriteLine()ステートメントとConsole.ReadLine()ステートメントをifステートメント内で囲むには、次のようにコードを更新します。if (petCount >= maxPets) { Console.WriteLine("Press the Enter key to continue."); readResult = Console.ReadLine(); } break; case "3":petCountの値は、whileループ内でインクリメントされます。petCountがmaxPetsと等しい場合、ourAnimals配列にペットを追加することはできません。 この状況が発生した場合は、ユーザーに通知する必要があります。Contoso Pets が容量に達したことをユーザーに通知するには、次のようにコードを更新します。
if (petCount >= maxPets) { Console.WriteLine("We have reached our limit on the number of pets that we can manage."); Console.WriteLine("Press the Enter key to continue."); readResult = Console.ReadLine(); } break; case "3":whileループ内のコードと、作成したユーザー メッセージを確認します。ユーザー メッセージを表示する
while (anotherPet == "y" && petCount < maxPets)ループとコードは、次のコードのようになります。while (anotherPet == "y" && petCount < maxPets) { // increment petCount (the array is zero-based, so we increment the counter after adding to the array) petCount = petCount + 1; // check maxPet limit if (petCount < maxPets) { // another pet? Console.WriteLine("Do you want to enter info for another pet (y/n)"); do { readResult = Console.ReadLine(); if (readResult != null) { anotherPet = readResult.ToLower(); } } while (anotherPet != "y" && anotherPet != "n"); } } if (petCount >= maxPets) { Console.WriteLine("We have reached our limit on the number of pets that we can manage."); Console.WriteLine("Press the Enter key to continue."); readResult = Console.ReadLine(); }Visual Studio Code の [ファイル] メニューで、[保存] を選択します。
Visual Studio Code で [統合ターミナル] パネルを開き、コマンドを入力してプログラムをビルドします。
続行する前に報告されたビルド エラーまたは警告を修正します。
作業を確認する
このタスクでは、統合ターミナルからアプリケーションを実行し、作成したループロジックと分岐ロジックが期待どおりに動作することを確認します。
必要に応じて、Visual Studio Code の統合ターミナル パネルを開きます。
ターミナルのコマンド プロンプトで、「dotnet run」と入力します。
ターミナルのコマンド プロンプトで、「2」と入力します。
次のメッセージが表示されることを確認します。
We currently have 4 pets that need homes. We can manage 4 more. Do you want to enter info for another pet (y/n)ターミナルのコマンド プロンプトで、「n」と入力します 。
"n" と入力したときに、コードが新しいペットを入力するためのループを終了することを確認します。
コード ロジックが想定どおりに動作している場合は、ターミナルにメイン メニューが表示されます。
想定どおりにコードがループを終了しない場合は、ターミナルで Ctrl キーを押しながら C キーを押して、強制的に実行を停止します。 コードを手動でステップ実行し、終了条件変数の値をトレースする必要があります。 必要に応じてコードを更新し、ユーザーが "n" を入力したときに
whileループを終了するようにします。 変更を保存し、プログラムをリビルドし、検証テストを実行して、この時点に戻ります。ターミナルのコマンド プロンプトで、「2」と入力します。
もう一度、次のメッセージが表示されます。
We currently have 4 pets that need homes. We can manage 4 more. Do you want to enter info for another pet (y/n)ターミナルのコマンド プロンプトで、「y」と入力します。
コードでの
petCountの使用方法を少し考えてみましょう。コードを検証する前に、コード ロジックを理解する必要があります。
この場合、コード ロジックは
petCountとmaxPetsの関係に依存します。maxPetsには8の値が割り当てられていることを知っていますが、petCountはどうでしょうか。 次の項目は、実装したロジックを評価するのに役立ちます。petCountループの最初のイテレーションに入るときに、4がwhileであると認識しています。petCountループが反復処理されるたびに、whileがインクリメントされることがわかります。petCountに割り当てられた値とpetCountのインクリメント方法が、ourAnimals配列へのデータの格納方法に影響を与えることがわかります。 次の項目では、petCountとourAnimalsに格納されているデータの関係について説明します。- アプリケーションは、サンプル データを作成するときに、
ourAnimals配列に 4 つのペットを追加します。 -
ourAnimalsの値がpetCountされると、アプリケーションは新しいデータを4配列に格納します。 これはバグではありません。 このコードは、配列要素が 0 から始まることを思い出すときに理にかなっています。 たとえば、ourAnimals[0,0]には動物1のペット ID が含まれており、ourAnimals[3,0]には動物4のペット ID が含まれます。 したがって、petCountが4場合は、5 番目のペットのデータを格納します。 - アプリケーションは、
petCountインクリメントする前に、ペット データを配列に格納します。 - アプリケーションは、別のペットの追加をユーザーに求めるメッセージを表示する前に、
petCountインクリメントします。 - アプリケーションで初めて別の ペットの情報を入力しますか (y/n) プロンプトが表示されたら、
petCountは既に5に設定されています。
- アプリケーションは、サンプル データを作成するときに、
ユーザーが最初に y と入力した場合、 別のペットの情報を入力しますか (y/n) というプロンプトは、次のようになります。
-
while (anotherPet == "y" && petCount < maxPets)ループが反復処理されます。anotherPet == "y"とpetCount < maxPetsのため、ループが反復処理されることがわかります。 -
petCountに割り当てられた値はインクリメントされます (whileループが反復処理されるときに)。 -
petCountに割り当てられた値は6されます (ユーザーが最初に y を入力した後)。
-
このコード ロジックの分析は、アプリケーションのテストを続ける際に念頭に置いておきます。
ターミナルパネルは「別のペット?」という同じメッセージで更新されますが、コードには更新された
petCountが表示されません。ターミナル パネルに次の出力が表示されます。
We currently have 4 pets that need homes. We can manage 4 more. Do you want to enter info for another pet (y/n) y Do you want to enter info for another pet (y/n)ターミナルのコマンド プロンプトで、「y」と入力します。
2 回目
y入力すると、petCountは7にインクリメントされます。 そのため、petCountはまだmaxPetsよりも小さいです。ターミナルのコマンド プロンプトで、「y」と入力します。
3 回目
y入力すると、petCountは8にインクリメントされます。 そのため、petCountは次のようになります。maxPets3 回目に
whileと入力したときに、コードが ループを終了することを確認します。ターミナル パネルに次の出力が表示されます。
We currently have 4 pets that need homes. We can manage 4 more. Do you want to enter info for another pet (y/n) y Do you want to enter info for another pet (y/n) y Do you want to enter info for another pet (y/n) y We have reached our limit on the number of pets that we can manage. Press the Enter key to continue.想定どおりにコードがループを終了しない場合は、コードを手動でステップ実行し、終了条件変数の値をトレースします。
petCountがmaxPetsと等しい値に達したときにループを終了するようにコードを更新します。petCountが既定値のmaxPetsを持つ8と等しいことがわかっているまで、"y" と答え続けます。ターミナル コマンド プロンプトで Enter キーを押して、アプリケーションの実行を続行します。
アプリケーションを終了し、ターミナル パネルを閉じます。