C# / الأساسي: البرامج ذات الأنواع وعقود الكائنات / الدرس 6
الاستثناءات وتنظيف الموارد المحدد
ميز الإدخال غير الصالح المتوقع من الفشل الاستثنائي واحفظ تحرير الموارد في كل خروج.
في هذه الصفحة
أهداف الدرس
- اختيار نتائج Try أوالاستثناء بالعقد.
- حفظ سياق الاستثناء والتقاطه عند حد مفيد.
- استخدام using وfinally دون خلط التخلص بالجمع.
الفشل جزء من عقد العملية
يشير الاستثناء لتعذر إكمال العقد. يناسب TryParse النص الخاطئ المعتاد أكثر من الرمي والالتقاط كل مرة. وقد يبرر الوسيط المطلوب الخاطئ ArgumentException أدق. اختر نموذجا متسقا ليعرف المستدعي ما يعالج. ينبغي أن يعرف المستدعي هل الرفض حدث طبيعي من المدخل أو إخفاق غير عادي في تنفيذ العقد.
لا تستخدم علامة عددية صالحة كبيانات. تعبر Try معخرج أونتيجة مجال أواستثناء عن حاجات مختلفة. ميز خرق الثابت من الغياب وفشل الموارد؛ ولا يجعل catch عام الجميع قابلا للاسترداد. لا تكفي معالجة كل الاستثناءات برسالة واحدة لإثبات إمكان المتابعة؛ يجب تحديد الحالة الصالحة التي ستستمر منها.
التقاط فشل محدد معروض
ينفذ المثال جمعا checked خارج المدى ويلتقط OverflowException فقط. الخرج رسالة تطبيق ثابتة لا نص تنفيذ مترجما محليا. هذا فشل تعليمي مضبوط؛ وقد يفضل API جمع عادي فحصا وTry. يوضح استخدام رسالة تطبيق ثابتة الفرق بين التحقق من سلوك المثال وبين الاعتماد على نص استثناء محلي.
ليكن للالتقاط استرداد أوترجمة أوتقرير مفيد. قد يفسد التقاط Exception والمتابعة حالة جزئية. إذا لم تصلح الطبقة الثابت أوتضف سياقا فدع الفشل للحد المالك بدلا من التسجيل والبلع المتكرر. عندما لا تستطيع الطبقة استرداد الحالة، يكون تمرير الاستثناء أكثر صدقا من تسجيله ثم استخدام نتيجة جزئية.
using System;
int maximum = int.MaxValue;
try
{
int result = checked(maximum + 1);
Console.WriteLine(result);
}
catch (OverflowException)
{
Console.WriteLine("addition rejected");
}
addition rejected
يرمي الجمع قبل استخدام نتيجة ويطبع الالتقاط المحدد رسالة ثابتة.
حفظ مسار التشخيص الأصلي
تحفظ throw; داخل catch معلومات المكدس الأصلية بينما تغير throw ex; سياق الإعادة وقد تخفي البداية. عند ترجمة الفئة العامة احفظ InnerException حيث يناسب ولا تكشف الأسرار في الرسالة. يحفظ الاستثناء الداخلي سبب الفشل عند إضافة سياق عام؛ يجب ألا تتحول الترجمة إلى فقد لمسار التشخيص.
استخدم المرشحات لتوضيح الفشل المناسب ولا تعامل الإلغاء عشوائيا كفشل عادي؛ ستحدد الدروس رمزه. تنفذ finally عند مغادرة المنطقة في الفك المدار المعتاد فتناسب تنظيف النجاح والاستثناء. تنظف finally مسارات الخروج المعتادة في الفك المدار، لكنها ليست ضمانا لكل توقف قسري للعملية.
التخلص من المورد عند نهاية نطاقه المنطقي
يملك المثال MemoryStream داخل using ويلاحظ الطول وهي حية ثم يتخلص قبل الرسالة الأخيرة. لا يفتح ملفا. الفكرة تنظيف محدد ينطبق على الملفات والمقابض التي لا تنتظر الجمع. لا يحتاج المثال إلى ملف خارجي لكي يثبت ترتيب الاستخدام والتخلص؛ يظل مفهوم الملكية نفسه قابلا للفحص.
تعبر using عن مسؤولية التخلص لا نسخا ولا اختفاء الذاكرة فورا. لا ينبغي لمساعد يستعير Stream التخلص منها إلا بنقل ملكية صريح. تقدم مغلفات leaveOpen أحيانا؛ اخترها من العلاقة الفعلية. إذا كان الغلاف مستعارا فاختيار إغلاق الدفق الأساسي أو تركه مفتوحا يجب أن يأتي من العقد لا من الراحة المؤقتة.
using System;
using System.IO;
using (var stream = new MemoryStream())
{
stream.WriteByte(7);
Console.WriteLine($"length={stream.Length}");
}
Console.WriteLine("scope complete");
length=1
scope complete
تكتب البايت والدفق حي وتتخلص using قبل السطر الأخير.
تصميم الملكية قبل catch
سجل المكتسب وعين مالكا لكل مورد. حرر المكتسب فقط عند فشل جزئي وعادة عكسيا. قد يفشل التنظيف فقرر الخطأ المحفوظ ولا تستبدل الأصل المفيد عرضا. لا تعني IDisposable أمان كل طريقة للتزامن أوسماح تكرار Dispose بالضرورة. يفيد ترتيب الحصول العكسي عندما يعتمد مورد لاحق على سابق، لكنه يظل محتاجا لحفظ الخطأ الأصلي المفيد.
اختبر النجاح وفشل الحصول والعمل والعودة المبكرة وافحص الحالة والنوع. قد يخفي البلع فقد بيانات وتسربا رغم عدم الانهيار. ليعد الكود المعاد استخدامه فشلا مفيدا ويقرر التطبيق العرض والخروج. اختبر أن المورد لم يبق مفتوحا وأن النتيجة لم تنشر جزئيا؛ لا يكفي أن الاستثناء أمكن التقاطه.
الأخطاء الشائعة وإصلاحها
يطبع catch خطأ ويترك حالة غير صالحة.
- لماذا يحدث؟
- افتُرض الاسترداد دون الثابت.
- كيف تصلحه؟
- استعد حالة صالحة أومرر الفشل.
- كيف تتجنب تكراره؟
- اختبر الحالة بعد الفشل.
تخفي الإعادة مكان الفشل.
- لماذا يحدث؟
- استُخدمت throw ex لاالإعادة المجردة.
- كيف تصلحه؟
- استخدم throw; للحفظ.
- كيف تتجنب تكراره؟
- راجع حدود الترجمة والداخلي.
يغلق دفق مستعار دون توقع.
- لماذا يحدث؟
- خُمنت مسؤولية التخلص.
- كيف تصلحه؟
- اترك المستعار مفتوحا إلا بنقل صريح.
- كيف تتجنب تكراره؟
- وثق الإنشاء والملكية والإبقاء مفتوحا.
اختبر فهمك
1. تفتح دالة موردين ويفشل الثاني. صف التنظيف والتقرير.
اعرض الحل المشروح
يظل الأول مملوكا فيتخلص منه مرة ولا يوجد ثان. احفظ فشل الحصول ولا تستبدله سرا بخطأ تنظيف. تعبر using متداخلة أومالك منظم عن العكس. لا تنشر نتيجة نصف مهيأة كنجاح.
2. لماذا لا يكفي الجمع لتحرير مقبض ملف سريعا ولو استعاد المغلف لاحقا؟
اعرض الحل المشروح
يتبع توقيت الجمع الذاكرة لا موعد ملكية الملف. المقابض خارجية محدودة ولا يمثل الإنهاء النهائي تنظيفا سريعا أوبديلا لـDispose. استخدم using أوfinally بعمر لازم فقط واختبر الاستثناء والعودة المبكرة.
أهم ما تعلمته
- التقط حيث يفيد الاسترداد أوالترجمة.
- التخلص ملكية محددة والجمع استعادة ذاكرة.
- تفحص اختبارات الفشل الحالة والتنظيف لاالبقاء فقط.