يكرر:تصميم الاستثناءات المخصصة:هل يجب علي تنفيذ المنشئ الافتراضي؟منشئ "الاستثناء الداخلي"؟

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

سؤال

الجواب على ما هي الطريقة الصحيحة لجعل الاستثناءات قابلة للتسلسل؟ يقول أن التنفيذ الأساسي "الصحيح" للاستثناء المخصص يتضمن 4 عوامل:

[Serializable]
public class SerializableExceptionWithoutCustomProperties : Exception
{
    public SerializableExceptionWithoutCustomProperties()
    {
    }

    public SerializableExceptionWithoutCustomProperties(string message) 
        : base(message)
    {
    }

    public SerializableExceptionWithoutCustomProperties(string message, Exception innerException) 
        : base(message, innerException)
    {
    }

    // Without this constructor, deserialization will fail
    protected SerializableExceptionWithoutCustomProperties(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
    }
}

على الفور، أود أن أقول إن هذا اسم سيء حقًا لنوع الاستثناء.ولكن أبعد من ذلك،

  1. لأغراض التسلسل الثنائي، وهو ما كان يشير إليه سؤال SO، هل يجب علي تنفيذ جميع المنشئات الأربعة؟أعتقد أنه لأغراض [Serializable]، يجب أن أقدم مُنشئًا يقبل وسيطتين من النوع (SerializationInfo، StreamingContext)، لأن الاستثناء مشتق من System.Exception، الذي يقوم بنفسه بإجراء تسلسل مخصص.أستطيع أن أفهم ذلك.لكن هل يجب أن أقوم بتنفيذ العوامل الأخرى، من أجل توفير استثناء قابل للتسلسل بشكل صحيح؟أعلم أنه إذا كنت أرغب في السماح لنوع ما بأن يكون قابلاً للتسلسل بتنسيق XML، فأنا بحاجة إلى توفير المرجع الافتراضي (no-op).هل ينطبق الشيء نفسه على [Serializable]؟للحظة، دعونا نقتصر على الاهتمام الضيق بـ [Serializable]، ونترك جانبًا أي إرشادات أوسع فيما يتعلق بـ "تصميم الإطار".

  2. ننتقل إلى السؤال الأوسع: تقول المبادئ التوجيهية الذي - التي يجب أن تنفذ الاستثناءات المخصصة العوامل الأربعة الشائعة.ما هو السبب وراء هذا المبدأ التوجيهي؟إذا قمت بتصميم استثناء مخصص، فهل هذا سلوك سيء حقًا، أو حتى خطأ، إذا لم أقدم مُنشئًا فارغًا/افتراضيًا؟هل هذا سلوك سيء حقًا، أو حتى خطأ، إذا لم أقدم مُنشئًا يسمح بـInnerException؟لماذا؟ضع في اعتبارك الحالة التي تم فيها إنشاء الاستثناء المخصص الخاص بي ضمن رمز مكتبتي، والمثيلات الوحيدة التي قمت بإلقاءها تتضمن رسالة، ولا يوجد استثناء داخلي.

  3. باختصار، هل التعليمة البرمجية التالية مقبولة للاستثناء المخصص الذي لا يوفر أي خصائص إضافية؟


[Serializable]
public class CustomException : Exception
{
    public CustomException(string message) : base(message) { }

    // Without this constructor, deserialization will fail
    protected CustomException(SerializationInfo info, StreamingContext context) 
        : base(info, context) { }
}

أنظر أيضا: مدونة الشتاء:جعل الاستثناءات قابلة للتسلسل.

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

المحلول 4

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

نصائح أخرى

تحذير تحليل الكود ذو الصلة هو CA1032، و الصفحه المرجعيه يقدم هذا التبرير:

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

يمكنك أنت فقط أو فريق المشروع الخاص بك تحديد ما إذا كان موقفك يستدعي استثناءً (عذرًا...)

مرحبًا، أعلم أن Microsoft نصحت بذلك على الأقل.إذا كنت تستخدم VS2008 (أو ربما الإصدارات السابقة)، فيمكنك بسهولة السماح لـ Visual Studio بإنشائها لك عن طريق الكتابة

exception

في المحرر والضغط على Tab (مرتين؟).سيؤدي هذا إلى إنشائها، مما يمنحك الفرصة لمنح الفصل اسمًا جديدًا.

اقتراح:إذا كان الآخرون سيستخدمون الاستثناء الخاص بك، وبما أن هؤلاء الآخرين سيكونون على دراية باستثناءات .NET، فلماذا لا تتبع الإرشادات فقط؟وهي نفسها التي يستخدمها .NET Framework.

هل تشعر أن هذا يتطلب الكثير من العمل، نظرًا لعدد أنواع الاستثناءات المخصصة التي تحددها؟إذا كان الأمر كذلك، فسيكون هذا سببًا آخر لاتباع الإرشادات، التي تنص على أنه لا ينبغي لك إنشاء عدد كبير من الاستثناءات المخصصة.

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