تمرين - إنشاء استثناء وطرحه
غالبا ما يحتاج المطورون إلى إنشاء استثناءات وطرحها من داخل أسلوب، ثم التقاط هذه الاستثناءات بشكل أكبر أسفل مكدس الاستدعاءات حيث يمكن التعامل معها. تساعدك معالجة الاستثناء على ضمان استقرار تطبيقاتك.
في هذا التمرين، ستبدأ بنموذج تطبيق يتضمن حالة خطأ محتملة داخل أسلوب يسمى . سيشكل throw الأسلوب المحدث استثناء عند اكتشاف المشكلة. ستتم معالجة الاستثناء في كتلة catch من التعليمات البرمجية التي تستدعي الأسلوب . والنتيجة هي تطبيق يوفر تجربة مستخدم أفضل.
إنشاء مشروع تعليمة برمجية جديدة
الخطوة الأولى هي إنشاء مشروع تعليمة برمجية يمكنك استخدامه أثناء هذه الوحدة النمطية.
افتح مثيلا جديدا من Visual Studio Code.
في القائمة ملف ، حدد فتح مجلد.
في مربع الحوار فتح مجلد ، انتقل إلى مجلد سطح مكتب Windows.
في مربع الحوار فتح مجلد ، حدد مجلد جديد.
قم بتسمية المجلد الجديد ThrowExceptions101، ثم حدد Select Folder.
في القائمة المحطة الطرفية، حدد محطة طرفية جديدة.
ستستخدم أمر .NET CLI لإنشاء تطبيق وحدة تحكم جديد.
في موجه أوامر لوحة TERMINAL، أدخل الأمر التالي:
dotnet new consoleأغلق لوحة TERMINAL.
مراجعة نموذج تطبيق
استخدم الخطوات التالية لتحميل نموذج التطبيق ومراجعته.
افتح ملف Program.cs.
في القائمة عرض، حدد لوحة الأوامر.
في موجه الأوامر، أدخل .net: g ثم حدد .NET: Generate Assets for Build and Debug.
استبدل محتويات ملف Program.cs بالتعليمات البرمجية التالية:
// Prompt the user for the lower and upper bounds Console.Write("Enter the lower bound: "); int lowerBound = int.Parse(Console.ReadLine()); Console.Write("Enter the upper bound: "); int upperBound = int.Parse(Console.ReadLine()); decimal averageValue = 0; // Calculate the sum of the even numbers between the bounds averageValue = AverageOfEvenNumbers(lowerBound, upperBound); // Display the value returned by AverageOfEvenNumbers in the console Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}."); // Wait for user input Console.ReadLine(); static decimal AverageOfEvenNumbers(int lowerBound, int upperBound) { int sum = 0; int count = 0; decimal average = 0; for (int i = lowerBound; i <= upperBound; i++) { if (i % 2 == 0) { sum += i; count++; } } average = (decimal)sum / count; return average; }خذ دقيقة لمراجعة التعليمات البرمجية.
لاحظ أن التطبيق ينفذ المهام التالية:
تستخدم
Console.ReadLine()عبارات المستوى الأعلى عبارات للحصول على قيم لlowerBoundوupperBound.تمر
lowerBoundعبارات المستوى الأعلى وupperBoundكوسيطات عند استدعاءAverageOfEvenNumbersالأسلوب .AverageOfEvenNumbersيقوم الأسلوب بتنفيذ المهام التالية:- يعلن عن المتغيرات المحلية المستخدمة في العمليات الحسابية.
- يستخدم تكرار حلقي
forلجمع الأرقام الزوجية بينlowerBoundوupperBound. يتم تخزين المجموع فيsum. - حساب عدد الأرقام المضمنة في المجموع. يتم تخزين العدد في
count. - يخزن متوسط الأرقام التي تم جمعها في متغير يسمى
average. يتم إرجاع قيمةaverage.
تقوم عبارات المستوى الأعلى بطباعة القيمة التي تم إرجاعها إلى
AverageOfEvenNumbersوحدة التحكم ثم إيقاف التنفيذ مؤقتا.
تكوين بيئة تتبع الأخطاء
يقرأ نموذج التطبيق إدخال المستخدم من وحدة التحكم. لا تدعم لوحة وحدة تحكم DEBUG قراءة الإدخال من وحدة التحكم. تحتاج إلى تحديث ملف launch.json قبل أن تتمكن من تشغيل هذا التطبيق في مصحح الأخطاء.
استخدم طريقة عرض EXPLORER لفتح ملف launch.json.
في ملف launch.json، قم بتحديث السمة
consoleكما يلي:// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console":"integratedTerminal",القيمة الافتراضية للسمة
consoleهيinternalConsole، والتي تتوافق مع لوحة وحدة تحكم DEBUG. لسوء الحظ، لا تدعم لوحة وحدة تحكم DEBUG إدخال وحدة التحكم. يتوافقintegratedTerminalالإعداد مع لوحة TERMINAL، التي تدعم إدخال وحدة التحكم والإخراج.احفظ التغييرات التي أجريتها على ملف launch.json، ثم أغلق الملف.
في قائمة Visual Studio Code Run ، حدد Start Debugging.
قم بالتبديل إلى لوحة TERMINAL.
في موجه "الحد الأدنى"، أدخل 3
في المطالبة "الحد الأعلى"، أدخل 11
لاحظ أن التطبيق يعرض الرسالة التالية ثم يتوقف مؤقتا:
The average of even numbers between 3 and 11 is 7.للخروج من التطبيق، اضغط على مفتاح الإدخال Enter.
طرح استثناء في الأسلوب AverageOfEvenNumbers
AverageOfEvenNumbers يتوقع الأسلوب حد أعلى أكبر من الحد السفلي.
DivideByZero يحدث خطأ إذا كان الحد السفلي أكبر من الحد الأعلى أو مساويا له.
تحتاج إلى تحديث AverageOfEvenNumbers الأسلوب لطرح استثناء عندما يكون الحد السفلي أكبر من الحد الأعلى أو مساويا له.
خذ دقيقة للنظر في الطريقة التي تريد بها معالجة المشكلة.
أحد الخيارات هو التفاف حساب
averageداخل كتلة التعليمات البرمجيةtrycatchوالاستثناءDivideByZeroعند حدوثه. يمكنك إعادة وضع الاستثناء ثم معالجته في التعليمات البرمجية للاتصال.خيار آخر هو تقييم معلمات الإدخال قبل بدء العمليات الحسابية. إذا كان
lowerBoundأكبر من أو يساويupperBound، يمكنك طرح استثناء.تقييم المعلمات وطرح استثناء قبل بدء العمليات الحسابية هو الخيار الأفضل.
ضع في اعتبارك نوع الاستثناء الذي يجب طرحه.
هناك نوعان من الاستثناءات التي تتوافق مع المشكلة:
-
ArgumentOutOfRangeExceptionArgumentOutOfRangeException- يجب طرح نوع استثناء فقط عندما تكون قيمة الوسيطة خارج نطاق القيم المسموح به كما هو محدد بواسطة الأسلوب الذي تم استدعاؤه. على الرغم من عدمAverageOfEvenNumbersتحديد نطاق مسموح به بشكل صريح لlowerBoundأوupperBound، فإن قيمةlowerBoundتعني النطاق المسموح به لupperBound. -
InvalidOperationExceptionInvalidOperationException: يجب طرح نوع استثناء فقط عندما لا تدعم شروط تشغيل الأسلوب الإكمال الناجح لاستدعاء أسلوب معين. في هذه الحالة، يتم تأسيس شروط التشغيل بواسطة معلمات الإدخال للأسلوب.
عندما يكون لديك نوعان أو أكثر من أنواع الاستثناءات للاختيار من بينها، حدد نوع الاستثناء الذي يناسب المشكلة بشكل أوثق. في هذه الحالة، يتم محاذاة نوعي الاستثناء إلى المشكلة بالتساوي.
عندما يكون لديك نوعان أو أكثر من أنواع الاستثناءات التي تتم محاذاتها مع المشكلة بشكل متساو، حدد نوع الاستثناء الأكثر ضيق النطاق.
ArgumentOutOfRangeExceptionيتم تحديد نطاق نوع الاستثناء إلى الوسيطات التي تم تمريرها إلى الأسلوب .InvalidOperationExceptionيتم تحديد نطاق نوع الاستثناء لشروط تشغيل الأسلوب. في هذه الحالة، يكون نوع الاستثناءArgumentOutOfRangeExceptionأكثر تضييقا من نوع الاستثناءInvalidOperationException.AverageOfEvenNumbersيجب أن يطرحArgumentOutOfRangeExceptionالأسلوب استثناء.-
في الجزء العلوي من
AverageOfEvenNumbersالأسلوب، للكشف عن مشكلة الحد الأعلى، قم بتحديث التعليمات البرمجية الخاصة بك كما يلي:if (lowerBound >= upperBound) { } int sum = 0;لإنشاء استثناء وطرحه
ArgumentOutOfRangeException، قم بتحديث كتلة التعليمات البرمجيةifكما يلي:if (lowerBound >= upperBound) { throw new ArgumentOutOfRangeException("upperBound", "ArgumentOutOfRangeException: upper bound must be greater than lower bound."); }يقوم سطر التعليمات البرمجية هذا بتهيئة مثيل جديد للفئة
ArgumentOutOfRangeExceptionباسم معلمة الإدخال التي تتسبب في الاستثناء ورسالة خطأ محددة.
التقاط الاستثناء في التعليمة البرمجية للاتصال
كلما أمكن، يجب اكتشاف الاستثناءات على مستوى مكدس الاستدعاءات حيث يمكن معالجتها. في نموذج التطبيق هذا، يمكن إدارة معلمات AverageOfEvenNumbers الأسلوب في أسلوب الاستدعاء (عبارات المستوى الأعلى).
مرر لأعلى إلى عبارات المستوى الأعلى.
لإحاطة
AverageOfEvenNumbersاستدعاء الأسلوب وعقبةConsole.WriteLineداخل كتلة التعليمات البرمجيةtry، قم بتحديث التعليمات البرمجية الخاصة بك كما يلي:try { // Calculate the sum of the even numbers between the bounds averageValue = AverageOfEvenNumbers(lowerBound, upperBound); // Display the result to the user Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}."); }لإنشاء العبارة المقترنة
catch، أدخل التعليمات البرمجية التالية:catch(ArgumentOutOfRangeException ex) { }خذ دقيقة للنظر في كيفية التعامل مع الاستثناء.
لمعالجة هذا الاستثناء، يجب أن تقوم التعليمات البرمجية بما يلي:
- شرح المشكلة للمستخدم.
- الحصول على قيمة جديدة ل
upperBound. - اتصل
AverageOfEvenNumbersباستخدام الجديدupperBound. - تابع إلى
catchالاستثناء إذا كان الجديدupperBoundالمقدم لا يزال أقل من أو يساويlowerBound.
يتطلب المتابعة إلى
catchالاستثناء تكرارا حلقيا. نظرا لأنك تريد استدعاءAverageOfEvenNumbersالأسلوب مرة واحدة على الأقل،doيجب استخدام حلقة.لتضمين
tryكتل وcatchداخلdoحلقة، قم بتحديث التعليمات البرمجية الخاصة بك كما يلي:do { try { // Calculate the sum of the even numbers between the bounds averageValue = AverageOfEvenNumbers(lowerBound, upperBound); // Display the result to the user Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}."); } catch (ArgumentOutOfRangeException ex) { } }whileالتعبير مطلوب لتعريف شرط الخروج من التكرارdoالحلقي. من الصعب تحديد الشرط قبل تعريف محتويات كتلة التعليمات البرمجيةdo. سيساعدك إكمال كتلة التعليماتcatchالبرمجية علىwhileتحديد التعبير المطلوب.لشرح المشكلة للمستخدم والحصول على جديد
upperBound، قم بتحديث كتلة التعليمات البرمجية الخاصة بكcatchكما يلي:catch (ArgumentOutOfRangeException ex) { Console.WriteLine("An error has occurred."); Console.WriteLine(ex.Message); Console.WriteLine($"The upper bound must be greater than {lowerBound}"); Console.Write($"Enter a new upper bound: "); upperBound = int.Parse(Console.ReadLine()); }تصف كتلة التعليمات البرمجية المحدثة
catchالمشكلة وتتطلب من المستخدم إدخال حد أعلى جديد. ومع ذلك، ماذا لو لم يكن لدى المستخدم قيمة حد أعلى صالحة لإدخالها؟ ماذا لو احتاج المستخدم إلى إنهاء التكرار الحلقي بدلا من إدخال قيمة؟لتزويد المستخدم بخيار للخروج من الحلقة بدلا من إدخال حد أعلى جديد، قم بتحديث كتلة التعليمات البرمجية الخاصة بك
catchكما يلي:catch (ArgumentOutOfRangeException ex) { Console.WriteLine("An error has occurred."); Console.WriteLine(ex.Message); Console.WriteLine($"The upper bound must be greater than {lowerBound}"); Console.Write($"Enter a new upper bound (or enter Exit to quit): "); string? userResponse = Console.ReadLine(); if (userResponse.ToLower().Contains("exit")) { } else { upperBound = int.Parse(userResponse); } }تتضمن كتلة التعليمات البرمجية المحدثة
catchمسارين، مسار "إنهاء" ومسار "حد أعلى جديد".خذ دقيقة للنظر في
whileالتعبير المطلوب للحلقةdo.إذا أدخل المستخدم "Exit" عند المطالبة، يجب أن تخرج التعليمات البرمجية من التكرار الحلقي. إذا أدخل المستخدم حد أعلى جديدا، يجب أن تستمر الحلقة.
whileيمكن استخدام تعبير يقيم قيمة منطقية. على سبيل المثال:while (exit == false);سينشئ التعبير المقترح
whileالسلوك التالي:- سيستمر التكرار
doالحلقي في التكرار طالما أن القيمة المنطقيةexitتساويfalse. - ستتوقف الحلقة
doعن التكرار بمجرد أن تكون القيمة المنطقيةexitمساوية لtrue.
- سيستمر التكرار
لإنشاء مثيل لمتغير منطقي يسمى
exit، واستخدامexitلتعيين شرط الخروج من التكرارdoالحلقي، قم بتحديث التعليمات البرمجية الخاصة بك كما يلي:bool exit = false; do { try { // Calculate the sum of the even numbers between the bounds averageValue = AverageOfEvenNumbers(lowerBound, upperBound); // Display the result to the user Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}."); exit = true; } catch (ArgumentOutOfRangeException ex) { Console.WriteLine("An error has occurred."); Console.WriteLine(ex.Message); Console.WriteLine($"The upper bound must be greater than {lowerBound}"); Console.Write($"Enter a new upper bound (or enter Exit to quit): "); string? userResponse = Console.ReadLine(); if (userResponse.ToLower().Contains("exit")) { exit = true; } else { exit = false; upperBound = int.Parse(userResponse); } } } while (exit == false);احفظ التعليمات البرمجية المحدثة.
في قائمة Run ، حدد Start Debugging.
قم بالتبديل إلى لوحة TERMINAL.
في موجه "الحد الأدنى"، أدخل 3
في المطالبة "الحد الأعلى"، أدخل 3
لاحظ أنه يتم عرض الإخراج التالي في لوحة TERMINAL:
Enter the lower bound: 3 Enter the upper bound: 3 An error has occurred. ArgumentOutOfRangeException: upper bound must be greater than lower bound. (Parameter 'upperBound') The upper bound must be greater than 3 Enter a new upper bound (or enter Exit to quit):في المطالبة بخط أعلى جديد، أدخل 11
لاحظ أنه يتم عرض الإخراج التالي في لوحة TERMINAL:
Enter the lower bound: 3 Enter the upper bound: 3 An error has occurred. ArgumentOutOfRangeException: upper bound must be greater than lower bound. (Parameter 'upperBound') The upper bound must be greater than 3 Enter a new upper bound (or enter Exit to quit): 11 The average of even numbers between 3 and 11 is 7.للخروج من التطبيق، اضغط على مفتاح الإدخال Enter.
تهانينا! لقد نجحت في طرح استثناء والقبض عليه والتعامل معه.
خلاصة
فيما يلي بعض الأشياء المهمة التي يجب تذكرها من هذه الوحدة:
- تأكد من تكوين بيئة تتبع الأخطاء الخاصة بك لدعم متطلبات التطبيق الخاص بك.
- يجب أن تطرح التعليمات البرمجية للأسلوب استثناء عند اكتشاف مشكلة أو شرط.
- يجب اكتشاف الاستثناءات على مستوى في مكدس الاستدعاءات حيث يمكن حلها.