C#: مقال حول رمي النوع المناسب من الاستثناء

StackOverflow https://stackoverflow.com/questions/4064198

  •  27-09-2019
  •  | 
  •  

سؤال

في بعض الأحيان لا أعرف نوع الاستثناء الساحر يجب أن أرمي. لذلك عادة ما أرمي استثناء (). هل هناك مقال لطيف حول هذا؟

هل كانت مفيدة؟

المحلول

إذا كنت لا تبذل أي محاولة للتعافي من خطأ ، يمكنك فقط رمي ملف Exception مع سلسلة لإخبارك بما حدث. (أو إذا كنت ستنفذ نفس الإجراء بغض النظر عن الخطأ الذي حدث).

بخلاف جعل الأمر واضحًا لمبرمج ما حدث خطأً باستخدام اسم استثناء جديد بدلاً من وضعه في الرسالة ، ويمكن أن يحتوي الاستثناء على بيانات لمساعدتك على التعافي من استثناء معين.

على سبيل المثال ، أ ArgumentNullException لديه خاصية ParamName, ، والتي يجب أن تضعها عند رمي الاستثناء. عندما يمسكها المتصل ، يمكنه بعد ذلك البحث عن هذه الخاصية وتقرر تمرير قيمة جديدة للوسيطة التي تسببت في الخطأ ، أو يمكنه طباعة خطأ ذي صلة لإبلاغ المبرمج بما حدث خطأ.

من المؤسف أن الاستثناءات نادراً ما يتم استخدامها في إمكاناتها الكاملة (في العديد من واجهات برمجة التطبيقات مفتوحة المصدر وكذا) ، وغالبًا ما يتم إدراجها ببساطة لإبلاغ مبرمج ما الخطأ الذي حدث. لا يوجد فرق كبير بين هذين 2 إذا كنت لا تخطط لقراءة ParamName الخاصية عند التقاطها. (الكثير من الناس لن يزعجوا ، ويلتقطون فقط Exception على أي حال).

throw new ArgumentNullException("arg1");
throw new Exception("arg1 is null");

قد يكون من الصعب التعافي من خطأ بالكامل ، ولكن في بعض التطبيقات ، قد تجد أنه من المستحسن إنشاء استثناءات مخصصة يمكن أن توفر جميع التفاصيل التي تحتاجها.

في الوقت الحالي ، أود فقط أن أضع Exception في بحث متصفح الكائن في VS ، وانظر ما هو موجود بالفعل. أسمائهم توضيحية ذاتية إلى حد ما ، لذلك يجب أن تكون قادرًا على اختيار شيء مناسب.

نصائح أخرى

تكمن مشكلة رمي استثناء عام في أنه يقيد قدرة الكود الخاص بك إلى زيادة المكدس بشكل صحيح (أي أفضل الممارسات هو فخ الاستثناء الأكثر تحديداً قبل التراجع ، والتقاط ما يمكنك التعامل معه فقط).

لدى Jeffrey Richter قسم ممتاز حول معالجة استثناء (بما في ذلك معلومات عن System.Exception Pace) في CLR عبر C#

تغطي "إرشادات تصميم الإطار" من تأليف Cwalina و Abrahms هذا الموضوع جيدًا (IMHO).

إنه متوفر مجانًا عبر الإنترنت هنا, أو الكتاب (غير مجاني) هنا (المملكة المتحدة) أو هنا (الولايات المتحدة). انظر في القسم بعنوان إرشادات التصميم للاستثناءات.

حسنًا ، الشيء الوحيد الذي لا يجب عليك فعله هو رمي Exception بحد ذاتها.
ابحث دائمًا عن فئة فرعية مناسبة.

لا أعرف أي منشور يتهجى أي استثناء يجب رميه عندما ، ولكن ArgumentException و InvalidOperationException يجب أن تعتني بمعظم حالاتك.

اطرح أسئلة منفصلة حول حالات منفصلة إذا جاءوا.

أود أن أقترح تقسيم الاستثناءات إلى بعض الفئات بناءً على حالة النظام:

  1. فشلت الطريقة بطريقة لم تفعل شيئًا ؛ لم يتم إزعاج حالة أي بيانات أساسية ، وربما تكون صالحة. السيناريوهات النموذجية: محاولة الاسترداد من مجموعة غير موجودة ، أو إضافة واحد بالفعل. سيناريو محتمل آخر: مهلة الاتصالات في الحالات التي لا ينبغي أن تسبب فيها أي فقدان للبيانات (وقد تم إعادة إعادة تشغيل العملية إذا كانت المشكلة ببساطة أن الطرف الآخر كان ببساطة بطيئًا للغاية).
  2. فشلت الطريقة بطريقة قد تكون قد أزعجت بنية البيانات الأساسية ، أو قد يكون بنية البيانات الأساسية قد تالفة سابقًا. لا ينبغي محاولة عمليات أخرى مع بنية البيانات هذه ما لم يتم اتخاذ خطوات للتحقق منها. سيناريو آخر محتمل: تحدث مهلة اتصالات عندما يتم استرداد سجل جزئيًا ، وفقدت الآن البيانات المدعومة جزئيًا. اعتمادًا على البروتوكول ، قد يكون من الضروري إجراء بعض إجراءات الاسترداد على الاتصال ، أو لإغلاقه وبدء إجراء جديد.
  3. هناك شيء خاطئ بشكل خطير في حالة النظام ، ومن المحتمل أن يكون الانتعاش غير ممكن.

لسوء الحظ ، لا تتناسب استثناءات .NET الحالية أي شيء مثل هذا النمط ؛ كان من الجيد لو كان هناك قاعدة استثناء من النوع الذي تم استثناء أشياء مثل ThreadAbortException و CPUHASCAGTTHFIREEXCESTION ، واستثناء "طبيعي" ، وتم اشتقاق جميع الاستثناءات "العادية" من الاستثناء. أنا أفهم أن .NET 4.0 kludges إلى حد ما في مثل هذا التصميم ، لكنني لا أعرف الميكانيكا الدقيقة. في أي حال ، أود أن أقترح أن يتم تقسيم أي استثناءات محددة من قبل المستخدم إلى مجموعات على النحو الوارد أعلاه ، مع كل الاستثناءات في كل مجموعة تشارك سلفًا مشتركًا متميزًا عن المجموعات الأخرى.

هناك مقال كتبه Krzysztof Cwalina ("مهندس معماري رئيسي في فريق إطار العمل في Microsoft") اختيار النوع الصحيح من الاستثناء لرمي الذي يلقي بعض الضوء على هذا. إنه يتعامل مع اختيار الاستثناء الصحيح لرمي وتوجيهات على إنشاء استثناءات مخصصة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top