c# - أفضل استثناء لوسيطة نوع عام غير صالحة




generics exception (10)

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

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

إذا كان المستخدم يحاول تمرير شيء لم يكن تعدادًا ، فأنا أرمي InvalidOperationException.

تصحيح:

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

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

تحرير 2:

واحد آخر ممكن:

System.ComponentModel.InvalidEnumArgumentException  

يتم طرح الاستثناء عند استخدام الوسائط غير الصالحة التي تمثل العدادين.

أنا حاليا أكتب بعض التعليمات البرمجية لـ UnconstrainedMelody التي لديها طرق عامة للقيام بها مع التعدادات.

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

فقط لجعل هذا ملموس ، إذا كان لدي شيء من هذا القبيل:

// Returns a value with all bits set by any values
public static T GetBitMask<T>() where T : struct, IEnumConstraint
{
    if (!IsFlags<T>()) // This method doesn't throw
    {
        throw new ???
    }
    // Normal work here
}

ما هو أفضل استثناء لرمي؟ ArgumentException يبدو منطقيًا ، لكنه عبارة عن وسيطة نوع أكثر من حجة عادية ، والتي يمكن أن تخلط بين الأشياء بسهولة. هل يجب علي تقديم فئة TypeArgumentException الخاصة TypeArgumentException ؟ استخدم InvalidOperationException ؟ NotSupportedException ؟ أي شيء آخر؟

أنا أفضل عدم إنشاء استثناء خاص بي لهذا إلا إذا كان من الواضح أن الشيء الصحيح الذي ينبغي عمله.


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


على ما يبدو ، يستخدم Microsoft ArgumentException لذلك ، كما هو موضح على سبيل المثال من Expression.Lambda<> أو Enum.TryParse<> أو Marshal.GetDelegateForFunctionPointer<> في المقطع استثناءات. لم أجد أي مثال يشير إلى خلاف ذلك ، إما (على الرغم من البحث عن مصدر مرجعي محلي لـ TDelegate و TEnum ).

لذا ، أعتقد أنه من الآمن أن نفترض أنه على الأقل في التعليمات البرمجية لـ Microsoft ، من المعتاد استخدام ArgumentException لوسائط كتابة عامة غير صالحة جانباً من المتغيرات الأساسية. وبالنظر إلى أن وصف الاستثناء في docs لا يميز بين تلك ، فهو ليس امتدادًا كبيرًا أيضًا.

نأمل أن يقرر السؤال الأمور مرة واحدة وإلى الأبد.


أصوات NotSupportedException تبدو كما لو أنها مناسبة بشكل واضح ، ولكن الوثائق تنص بوضوح على أنه يجب استخدامها لغرض مختلف. من ملاحظات فئة MSDN:

هناك أساليب غير معتمدة في الفئة الأساسية ، مع توقع تنفيذ هذه الطرق في الفئات المشتقة بدلاً من ذلك. قد تقوم الفئة المشتقة بتطبيق مجموعة فرعية فقط من الأساليب من الفئة الأساسية ، ورمي NotSupportedException للأساليب غير المدعومة.

بالطبع ، هناك طريقة في NotSupportedException من الواضح أنها جيدة بما فيه الكفاية ، ولا سيما بالنظر إلى المعنى العام. بعد قولي هذا ، لست متأكدا مما إذا كان هذا صحيحًا.

نظرا لغرض غير UnconstrainedMelody ...

هناك العديد من الأشياء المفيدة التي يمكن القيام بها باستخدام أساليب / فئات عامة حيث يكون هناك قيد من النوع "T: enum" أو "T: delegate" - ولكن للأسف ، يتم حظر تلك في C #.

تعمل هذه المكتبة فائدة حول المحظورات باستخدام ildasm / ilasm ...

... يبدو وكأنه قد يكون هناك Exception جديد بالترتيب على الرغم من العبء الكبير من الإثبات الذي نحتاجه حقًا للالتقاء قبل إنشاء Exceptions مخصصة. قد يكون شيء من هذا القبيل InvalidTypeParameterException مفيدًا في المكتبة (أو ربما لا - هذه بالتأكيد حالة حافة ، أليس كذلك؟).

هل سيكون العملاء قادرين على تمييز ذلك عن استثناءات BCL؟ متى يمكن لعميل ما أن يطلق هذا عن طريق الخطأ باستخدام enum الفانيليا؟ كيف تجيب على الأسئلة التي طرحتها الإجابة المقبولة على ما هي العوامل التي يجب أخذها في الاعتبار عند كتابة فصل استثناء مخصص؟


معرف الذهاب مع NotSupportedExpcetion.


يجب ألا يتم رمي البرمجة العامة في وقت التشغيل لمعلمات النوع غير الصالحة. يجب أن لا ترجمة ، يجب أن يكون لديك وقت تنفيذ الترجمة. لا أعرف ما IsFlag<T>() ، ولكن ربما يمكنك تحويل هذا إلى فرض وقت تجميع ، مثل محاولة إنشاء نوع يمكن IsFlag<T>() فقط باستخدام "علامات". ربما يمكن لصف traits أن يساعد.

تحديث

إذا كان يجب عليك إلقاء ، فقم بالتصويت لـ InvalidOperationException. الاستنتاج هو أن الأنواع العامة تحتوي على معلمات وأخطاء تتعلق بمعلمات (method) تتمحور حول التسلسل الهرمي ArgumentException. ومع ذلك ، ينص recommendation على ArgumentException ذلك

إذا لم يتضمن الفشل الحجج نفسها ، فيجب استخدام InvalidOperationException.

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


سأذهب مع NotSupportedException . على الرغم من أن ArgumentException يبدو جيدًا ، إلا أنه يُتوقع فعلًا عندما تكون الوسيطة التي تم تمريرها إلى إحدى الطرق غير مقبولة. تعتبر وسيطة النوع خاصية مميزة للطريقة الفعلية التي تريد الاتصال بها ، وليست "وسيطة" حقيقية. يجب طرح InvalidOperationException عندما تكون العملية التي تقوم بها صالحة في بعض الحالات ولكن في حالة معينة ، تكون غير مقبولة.

يتم طرح NotSupportedException عندما تكون العملية غير مدعومة بطبيعتها. على سبيل المثال ، عند تنفيذ واجهة لا يكون فيها عضو معين منطقيًا لفئة معينة. هذا يبدو وكأنه وضع مماثل.


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


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

أعتقد أن InvalidOperationException هو الاستثناء الأكثر ملاءمةً الذي يمكنك تنفيذه هنا.


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

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

ملاحظات:

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

  2. إذا كنت لا تستطيع تحمل متغير عالمي ، قم بتعريفه في main () وقم بتمريره عند الحاجة ...





c# generics exception