سؤال

هذا يقلقني حقًا، لذا آمل أن يقدم لي شخص ما مبررًا معقولًا لسبب وجود الأمور على ما هي عليه.

NotImplementedException. أنت تسحب ساقي، أليس كذلك؟

على الرغم من أن هذا مضحك جدًا، إلا أن هناك مشكلة أكثر خطورة في ذهني.

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

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

هذا جنون.مجنون.مجنون.لذا فإن السؤال هو: لماذا يوجد NotImplementedException?

كضربة استباقية ، لا أريد أن يرد أي شخص ، "لأن المصممين بحاجة إلى وضع هذا في الكود الذي تم إنشاؤه تلقائيا". هذا أمر فظيع.أفضّل ألا يتم تجميع التعليمات البرمجية التي تم إنشاؤها تلقائيًا حتى تقوم بتوفير التنفيذ.على سبيل المثال ، يمكن أن يكون التنفيذ الذي تم إنشاؤه تلقائيا هو "رمي NotImplementException ؛" حيث لم يتم تعريف NotImplementException !

هل سبق لأي شخص اكتشاف NotImplementedException والتعامل معه؟هل سبق لك أن تركت NotImplementedException في التعليمات البرمجية الخاصة بك؟إذا كان الأمر كذلك، فهل يمثل ذلك قنبلة موقوتة (أي أنك تركتها هناك عن طريق الخطأ)، أو عيبًا في التصميم (لا ينبغي تنفيذ الطريقة ولن يتم استدعاؤها أبدًا)؟

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

معلومات إضافية:

هذا هي قراءة مثيرة للاهتمام حول هذا الموضوع.

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

تعليقات من جاريد بارسونز ضعيفة جدًا وربما ينبغي تجاهلها:الاستثناء غير المنفذ:قم بطرح هذا الاستثناء عندما لا يقوم النوع بتنفيذ طريقة لأي سبب آخر.

ال MSDN بل إنه أضعف في هذا الموضوع، حيث يذكر فقط أن "الاستثناء الذي يتم طرحه عند عدم تنفيذ الطريقة أو العملية المطلوبة."

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

المحلول

هناك حالة واحدة أجدها مفيدة:تد.

أكتب اختباراتي، ثم أقوم بإنشاء بذرة حتى يتم تجميع الاختبارات.تلك بذرة لا تفعل شيئا سوى throw new NotImplementedException();.بهذه الطريقة ستفشل الاختبارات بشكل افتراضي، مهما حدث.إذا استخدمت بعض قيمة الإرجاع الوهمية، فقد يؤدي ذلك إلى ظهور نتائج إيجابية كاذبة.الآن بعد أن تم تجميع جميع الاختبارات وفشلها بسبب عدم وجود تنفيذ، أقوم بمعالجة تلك الجذور.

وبما أنني لا أستخدم أ NotImplementedException في أي حالة أخرى، لا NotImplementedException سوف يمرر رمز الإصدار أبدًا، لأنه سيؤدي دائمًا إلى فشل بعض الاختبارات.

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

يحرر:لقد كتبت قاعدة FxCop للعثور عليهم.

هذا هو الرمز:

using System;
using Microsoft.FxCop.Sdk;

/// <summary>
/// An FxCop rule to ensure no <see cref="NotImplementedException"/> is
/// left behind on production code.
/// </summary>
internal class DoNotRaiseNotImplementedException : BaseIntrospectionRule
{
    private TypeNode _notImplementedException;
    private Member _currentMember;

    public DoNotRaiseNotImplementedException()
        : base("DoNotRaiseNotImplementedException",
               // The following string must be the assembly name (here
               // Bevonn.CodeAnalysis) followed by a dot and then the
               // metadata file name without the xml extension (here
               // DesignRules). See the note at the end for more details.
               "Bevonn.CodeAnalysis.DesignRules",
               typeof (DoNotRaiseNotImplementedException).Assembly) { }

    public override void BeforeAnalysis()
    {
        base.BeforeAnalysis();
        _notImplementedException = FrameworkAssemblies.Mscorlib.GetType(
            Identifier.For("System"),
            Identifier.For("NotImplementedException"));
    }

    public override ProblemCollection Check(Member member)
    {
        var method = member as Method;
        if (method != null)
        {
            _currentMember = member;
            VisitStatements(method.Body.Statements);
        }
        return Problems;
    }

    public override void VisitThrow(ThrowNode throwInstruction)
    {
        if (throwInstruction.Expression != null &&
            throwInstruction.Expression.Type.IsAssignableTo(_notImplementedException))
        {
            var problem = new Problem(
                GetResolution(),
                throwInstruction.SourceContext,
                _currentMember.Name.Name);
            Problems.Add(problem);
        }
    }
}

وهذه هي البيانات الوصفية للقاعدة:

<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Bevonn Design Rules">
  <Rule TypeName="DoNotRaiseNotImplementedException" Category="Bevonn.Design" CheckId="BCA0001">
    <Name>Do not raise NotImplementedException</Name>
    <Description>NotImplementedException should not be used in production code.</Description>
    <Url>http://stackoverflow.com/questions/410719/notimplementedexception-are-they-kidding-me</Url>
    <Resolution>Implement the method or property accessor.</Resolution>
    <MessageLevel Certainty="100">CriticalError</MessageLevel>
    <Email></Email>
    <FixCategories>NonBreaking</FixCategories>
    <Owner></Owner>
  </Rule>
</Rules>

لبناء هذا تحتاج إلى:

  • مرجع Microsoft.FxCop.Sdk.dll و Microsoft.Cci.dll

  • ضع البيانات الوصفية في ملف يسمى DesignRules.xml وإضافته كمورد مضمن إلى التجميع الخاص بك

  • قم بتسمية التجميع الخاص بك Bevonn.CodeAnalysis.إذا كنت تريد استخدام أسماء مختلفة لبيانات التعريف أو ملفات التجميع، فتأكد من تغيير المعلمة الثانية إلى المُنشئ الأساسي وفقًا لذلك.

ثم قم ببساطة بإضافة التجميع الناتج إلى قواعد FxCop الخاصة بك وقم بإزالة تلك الاستثناءات اللعينة من التعليمات البرمجية الثمينة الخاصة بك.هناك بعض الحالات الزاوية حيث لن يتم الإبلاغ عن NotImplementedException عندما يتم طرحها ولكني أعتقد حقًا أنك ميؤوس منها إذا كنت تكتب بالفعل مثل هذا الكود cthulhian.للاستخدامات العادية، أي. throw new NotImplementedException();, إنه يعمل، وهذا هو كل ما يهم.

نصائح أخرى

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

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

سألخص آرائي حول هذا الأمر في مكان واحد، لأنها متناثرة في بعض التعليقات:

  1. انت تستخدم NotImplementedException للإشارة إلى أن عضو الواجهة لم يتم تنفيذه بعد، ولكنه سيتم تنفيذه.يمكنك دمج ذلك مع اختبار الوحدة الآلي أو اختبار ضمان الجودة لتحديد الميزات التي لا تزال بحاجة إلى التنفيذ.

  2. بمجرد تنفيذ الميزة، يمكنك إزالة NotImplementedException.تتم كتابة اختبارات وحدة جديدة للميزة للتأكد من أنها تعمل بشكل صحيح.

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

  4. السبب على حد سواء NotImplementedException و NotSupportedException وجودها في الإطار بسيط:المواقف التي تؤدي إليها شائعة، لذا فمن المنطقي تعريفها في إطار العمل، حتى لا يضطر المطورون إلى الاستمرار في إعادة تعريفها.كما أنه يسهل على العملاء معرفة الاستثناء الذي يجب اكتشافه (خاصة في سياق اختبار الوحدة).إذا كان عليك تحديد الاستثناء الخاص بك، فيجب عليهم معرفة الاستثناء الذي يجب التقاطه، وهو على الأقل مضيعة للوقت يؤدي إلى نتائج عكسية، وغالبًا ما يكون غير صحيح.

لماذا لا تنفذ استثناء تواجد؟

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

Is NotImplementException the C# ما يعادل جافا غير معتمد عملية استثناء؟

لا، يحتوي ‎.NET على NotSupportedException

لا بد لي من تشغيل الخوارزمية الخاصة بي ، والتقاط NotImplementExceptions وبعض كيف استرجاع طلبي إلى بعض دولة عاقلة

تحتوي واجهة برمجة التطبيقات الجيدة على وثائق أساليب XML التي تصف الاستثناءات المحتملة.

أنا متشكك جدا في NotSupportedException أيضا ...لا مدعم؟ماذا؟إذا لم يكن كذلك معتمد ، لماذا هو جزء من واجهه؟

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

الاستخدام الرئيسي لاستثناء NotImplementedException هو في كود كعب الروتين الذي تم إنشاؤه:بهذه الطريقة لا تنسى تنفيذها !!على سبيل المثال، سيقوم Visual Studio بتنفيذ أساليب/خصائص الواجهة بشكل صريح مع قيام الجسم بإلقاء NotImplementedException.

يكرر NotImplementedException - وهذا يخدم عدد قليل من الاستخدامات؛إنه يوفر استثناءً واحدًا (على سبيل المثال) يمكن أن يتم قفله لاختبارات الوحدة الخاصة بك للعمل غير المكتمل.ولكن أيضًا، فهو يفعل حقًا ما يقول:هذا ببساطة ليس موجودًا (حتى الآن).على سبيل المثال، "mono" يلقي هذا في كل مكان للطرق الموجودة في MS libs، ولكن لم تتم كتابتها بعد.

يكرر NotSupportedException - ليس كل شيء متوفراً.على سبيل المثال ، تدعم العديد من الواجهات زوجا "هل يمكنك القيام بذلك؟" / "افعل هذا".إذا كان "هل يمكنك القيام بذلك؟" إرجاع خطأ ، فمن المعقول تماما أن يرمي "افعل هذا" NotSupportedException.قد تكون الأمثلة IBindingList.SupportsSearching / IBindingList.Find() إلخ.

معظم المطورين في Microsoft على دراية بأنماط التصميم التي يكون فيها NotImplementedException مناسبًا.إنه أمر شائع إلى حد ما في الواقع.

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

لذلك في هذا المثال، سيكون هناك أسلوب GetFiles() لفئة الدليل، ومع ذلك، لن تقوم فئة الملف بتنفيذ هذه الطريقة، لأنه ليس من المنطقي القيام بذلك.بدلاً من ذلك، ستحصل على NotImplementedException، لأن الملف لا يحتوي على عناصر فرعية كما هو الحال في الدليل.

لاحظ أن هذا لا يقتصر على .NET - فسوف تجد هذا النمط في العديد من لغات ومنصات OO.

لماذا تشعر بالحاجة إلى التقاط كل استثناء ممكن؟هل تقوم بالتفاف كل طريقة استدعاء مع catch (NullReferenceException ex) أيضاً؟

رمي رمز كعب الروتين NotImplementedException هو عنصر نائب، إذا تم إصداره فيجب أن يكون خطأً تمامًا مثل NullReferenceException.

أعتقد أن هناك العديد من الأسباب وراء قيام MS بإضافة NotImplementedException إلى إطار العمل:

  • كوسيلة راحة؛نظرًا لأن العديد من المطورين سيحتاجون إليها أثناء التطوير، فلماذا يتعين على كل شخص أن ينشئ تطبيقه الخاص؟
  • حتى تتمكن الأدوات من الاعتماد على وجودها؛على سبيل المثال، يقوم أمر "Implement Interface" الخاص بـ Visual Studio بإنشاء بذرة الطريقة التي تطرح NotImplementedException.إذا لم يكن موجودًا في إطار العمل، فلن يكون هذا ممكنًا، أو على الأقل محرجًا إلى حد ما (على سبيل المثال، يمكن أن ينشئ تعليمات برمجية لا يتم تجميعها حتى تقوم بإضافة NotImplementedException الخاص بك)
  • لتشجيع "الممارسة القياسية" المتسقة

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

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

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

سببان:

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

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

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

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

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

أنت بحاجة إلى هذا الاستثناء لعملية التشغيل المتداخل لـ COM. إنها E_NOTIMPL.تُظهر المدونة المرتبطة أيضًا أسبابًا أخرى

رمي NotImplementedException هي الطريقة الأكثر منطقية لـ IDE لإنشاء كود كعب الروتين المترجم.كما هو الحال عندما تقوم بتوسيع الواجهة وتحصل على Visual Studio لإيقافها نيابةً عنك.

إذا قمت بعمل القليل من C++/COM، فهذا موجود هناك أيضًا، باستثناء أنه كان يُعرف باسم E_NOTIMPL.

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

وجود NotImplementedException يحدد بشكل جيد الطرق التي ليست جاهزة بعد، وفي نهاية اليوم يكون الأمر سهلاً مثل الضغط Ctrl+Shift+F للعثور عليها جميعًا، أنا متأكد أيضًا من أن أدوات تحليل التعليمات البرمجية الثابتة ستلتقطها أيضًا.

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

NotImplementedException

يتم طرح الاستثناء عندما لا يتم تنفيذ الطريقة أو العملية المطلوبة.

إن جعل هذا استثناءً واحدًا محددًا في .NET core يجعل من السهل العثور عليه والقضاء عليه.إذا كان على كل مطور إنشاء برنامج خاص به ACME.EmaNymton.NotImplementedException سيكون من الصعب العثور عليهم جميعًا.

NotSupportedException

يتم طرح الاستثناء عندما تكون الطريقة التي تم استدعاؤها غير مدعومة.

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

على سبيل المثال، تم إنشاء التكرارات (باستخدام yield الكلمة الأساسية) هي-أ IEnumerator, ، لكن ال IEnumerator.Reset رميات الطريقة NotSupportedException.

من ECMA-335، مواصفات CLI، على وجه التحديد أنواع مكتبة CLI، System.NotImplementedException، قسم الملاحظات:

"هناك عدد من الأنواع والبنيات، المحددة في مكان آخر في هذا المعيار، غير مطلوبة لتطبيقات واجهة سطر الأوامر (CLI) التي تتوافق فقط مع ملف تعريف Kernel.على سبيل المثال، تتكون مجموعة ميزات الفاصلة العائمة من أنواع بيانات الفاصلة العائمة System.Single وSystem.Double.إذا تم حذف دعم هذه العناصر من التطبيق، فإن أي محاولة للإشارة إلى توقيع يتضمن أنواع بيانات الفاصلة العائمة تؤدي إلى استثناء من النوع System.NotImplementedException."

لذا، فإن الاستثناء مخصص للتطبيقات التي تنفذ الحد الأدنى فقط من ملفات تعريف المطابقة.الحد الأدنى المطلوب من ملف التعريف هو ملف تعريف Kernel (راجع الإصدار الرابع من ECMA-335 - القسم الرابع، القسم 3)، والذي يتضمن BCL، ولهذا السبب يتم تضمين الاستثناء في "واجهة برمجة التطبيقات الأساسية"، وليس في أي موقع آخر.

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

أما سبب عدم تضمين هذه المعلومات في وثائق MSDN لتنفيذ MS لـ CLI فهو خارج عن ارادتي.

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

1) ترحيل تطبيق إلى قاعدة بيانات مختلفة غالبا ما يقال إن هذا نادرا ما يحدث أو يكون مطلوبا.هراء * ر.اخرج أكثر.

2) نفس قاعدة البيانات ، سائق مختلف أحدث مثال على ذلك كان عندما قام عميل يستخدم تطبيقا مدعوما من Access بالترقية من WinXP إلى Win7 x64.نظرًا لعدم وجود برنامج تشغيل JET 64 بت، قام موظف تكنولوجيا المعلومات لديهم بتثبيت AccessDatabaseEngine بدلاً من ذلك.عندما تعطل تطبيقنا، كان بإمكاننا أن نرى بسهولة من السجل أن DB.Connect تعطل مع NotSupportedException - وهو الأمر الذي تمكنا من معالجته بسرعة.ومن الأمثلة الحديثة الأخرى أحد المبرمجين لدينا الذين حاولوا استخدام المعاملات في قاعدة بيانات Access.على الرغم من أن Access يدعم المعاملات، إلا أن مكتبتنا لا تدعم معاملات Access (لأسباب خارج نطاق هذه المقالة).NotSupportedException، حان وقت التألق!

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

لا تعد NotSupportedException ميزة مهمة بأي حال من الأحوال ولكنها شيء أجد نفسي أستخدمه كثيرًا أثناء عملي في مشاريع أكبر.

لنفترض أن لديك هذه الطريقة في كود الإنتاج الخاص بك

public void DoSomething()

أي واحد ستأخذه إذا كنت تريد تركه لاحقًا للانتهاء منه؟

public void DoSomething()
{
}

أو

public void DoSomething()
{
    throw new NotImplementedException();
}

بالتأكيد سأغتنم الثانية.مقترنًا بـ Elmah أو أي آلية أخرى لتسجيل الأخطاء لديك (يتم تنفيذها كجانب عبر التطبيق بأكمله).جنبًا إلى جنب مع تصفية السجل/الاستثناء لتشغيل إشعار البريد الإلكتروني بوجود خطأ فادح عند اكتشافه.

الحجة القائلة بأن NotImplementedException == غير مكتملة ليست صحيحة أيضًا.(1) ينبغي ترك اصطياد الطرق غير المنفذة لاختبارات الوحدة/اختبارات التكامل.إذا كانت لديك تغطية 100% (وهو ما يجب عليك فعله الآن، مع وجود العديد من أدوات إنشاء التعليمات البرمجية الوهمية/كعب الروتين) مع عدم وجود NotImplementedException، فما هي مخاوفك؟(2) توليد الكود.عادي بسيط.مرة أخرى، إذا قمت بإنشاء الكود، واستخدمت نصف الكود الذي تم إنشاؤه فقط، فلماذا لا يكون لدي NotImplementedException في بقية كعب الروتين الذي تم إنشاؤه؟

إنه مثل القول بأنه لا ينبغي تجميع التعليمات البرمجية إلا إذا تم فحص/معالجة كل إدخال لاغٍ باعتباره فارغًا.(المعروف أيضًا باسم خطأ التريليون دولار، إن لم يكن أكثر).يجب أن تكون اللغة مرنة، بينما يجب أن تكون الاختبارات/العقود متينة.

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

يتم طرح NotImplementException لبعض طرق .NET (راجع المحلل اللغوي C # في Code DOM الذي لم يتم تنفيذه ، ولكن الطريقة موجودة!) يمكنك التحقق من هذه الطريقة Microsoft.CSharp.CSharpCodeProvider.Parse

كلاهما اختراق لمشكلتين شائعتين.

NotImplementedException هو حل بديل للمطورين الذين هم رواد فضاء في الهندسة المعمارية ويرغبون في كتابة واجهة برمجة التطبيقات (API) أولاً، ثم التعليمات البرمجية لاحقًا.من الواضح، بما أن هذه ليست عملية تدريجية، فلا يمكنك تنفيذ كل شيء مرة واحدة، وبالتالي تريد التظاهر بأنك قد انتهيت من تنفيذ NotImplementedException.

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

لذا، عندما تريد أن ترث سلوك الفئة الأصلية وتقييده، فإنك تقوم برمي NotSupported على الأساليب التي لا معنى لها في التقييد.

ماذا عن النماذج الأولية أو المشاريع غير المكتملة؟

لا أعتقد أن استخدام استثناء فكرة سيئة حقًا (على الرغم من أنني أستخدم مربع الرسائل في هذه الحالة).

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

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

لدي عدد قليل من NotImplementedExceptions في الكود الخاص بي.في كثير من الأحيان يأتي من جزء من واجهة أو فئة مجردة.بعض الأساليب التي أشعر أنني قد أحتاجها في المستقبل، فهي منطقية لكوني جزءًا من الفصل الدراسي، لكنني لا أريد أن أخصص وقتًا للإضافة إلا إذا كنت في حاجة إليها بالفعل.على سبيل المثال، لدي واجهة لجميع أنواع الإحصائيات الفردية في لعبتي.أحد هذه الأنواع هو ModStat، وهو مجموع الإحصائيات الأساسية بالإضافة إلى جميع المعدلات (أي الأسلحة والدروع والتعويذات).تحتوي واجهة الإحصائيات الخاصة بي على حدث OnChanged، لكن ModStat الخاص بي يعمل عن طريق حساب مجموع جميع الإحصائيات التي تشير إليها في كل مرة يتم استدعاؤها.لذلك بدلاً من رفع الحمل الزائد لعدد كبير من أحداث ModStat.OnChange في كل مرة يتغير فيها الإحصائيات، لدي فقط NotImplementedException الذي يتم طرحه إذا حاول أي شخص إضافة/إزالة مستمع إلى OnChange.

تتعلق لغات .NET بالإنتاجية، فلماذا تقضي وقتك في برمجة شيء لن تستخدمه حتى؟

هنا مثال واحد:في Java، كلما قمت بتنفيذ الواجهة Iterator, ، عليك تجاوز الأساليب الواضحة hasNext() و next(), ولكن هناك أيضا delete().في 99% من حالات الاستخدام التي أستخدمها، لا أحتاج إلى هذا، لذلك أقوم فقط برمي ملف NotImplementedException.وهذا أفضل بكثير من عدم القيام بأي شيء بصمت.

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

إذا كنت لا ترغب في استخدامه، فما عليك سوى تجاهله.إذا كان لديك كتلة من التعليمات البرمجية التي يعتمد نجاحها على نجاح كل جزء منها، ولكنها قد تفشل بينهما، فإن خيارك الوحيد هو التقاط القاعدة Exception واسترجاع ما يجب استرجاعه.ينسى NotImplementedException.قد يكون هناك الكثير من الاستثناءات، مثل MyRandomException و GtfoException و OmgLolException.بعد أن تكتب الكود في الأصل، يمكنني الوصول إليه ورمي نوع استثناء آخر من واجهة برمجة التطبيقات التي تتصل بها.واحدة لم تكن موجودة عندما كتبت الكود الخاص بك.تعامل مع الأشخاص الذين تعرف كيفية التعامل معهم والتراجع عن أي أشخاص آخرين، على سبيل المثال، catch(Exception).الأمر بسيط جدًا، على ما أعتقد..أجد أنه في متناول اليدين أيضا.خاصة عندما تحاول تجربة أشياء رائعة باستخدام اللغة/إطار العمل الذي يفرض عليك الأشياء أحيانًا.

أحد الأمثلة لدي هو التسلسل.لقد قمت بإضافة خصائص في مكتبة .NET الخاصة بي غير موجودة في قاعدة البيانات (على سبيل المثال، الأغلفة الملائمة فوق الخصائص "الغبية" الموجودة، مثل FullName الملكية التي تجمع FirstName, MiddleName, ، و LastName).ثم أرغب في إجراء تسلسل لأنواع البيانات هذه إلى XML لإرسالها عبر السلك (على سبيل المثال، من تطبيق ASP.NET إلى JavaScript)، ولكن إطار عمل التسلسل يقوم فقط بتسلسل الخصائص العامة مع كليهما get و set الملحقات.لا أريدك أن تكون قادرًا على التعيين FullName لأنه بعد ذلك سأضطر إلى تحليلها وقد يكون هناك تنسيق غير متوقع قمت بتحليله بشكل خاطئ وتخرج سلامة البيانات من النافذة.من الأسهل فقط استخدام الخصائص الأساسية لذلك، ولكن نظرًا لأن اللغة وواجهة برمجة التطبيقات (API) تتطلبان مني الحصول على set الوصول، وسوف رمي NotImplementedException (لم أكن على علم بذلك NotSupportedException حتى أقرأ هذا الموضوع، ولكن أحدهما يعمل) حتى إذا حاول بعض المبرمجين في المستقبل تعيينه FullName سيواجه الاستثناء أثناء الاختبار ويدرك خطأه.

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