سؤال

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

من الناحية المثالية، أود أن "تبدو" الطرق متشابهة؛يمكن أن يكون أحد الحلول هو تعريفهم على أنهم

public Point CalculatePoint(... out Boolean boSuccess);
public List<Point> CalculateListOfPoints(... out Boolean boSuccess);

أو بدلا من ذلك للعودة نقطة؟لـ CalculatePoint، وإرجاع قيمة خالية للإشارة إلى الفشل.وهذا يعني الاضطرار إلى الرجوع إلى النوع غير الفارغ، وهو ما يبدو مبالغًا فيه.

هناك طريق آخر يتمثل في إرجاع boolean boSuccess، والحصول على النتيجة (نقطة أو قائمة) كمعلمة "خارج"، وتسميتها TryToCalculatePoint أو شيء من هذا القبيل...

ما هي أفضل الممارسات؟

يحرر:لا أريد استخدام الاستثناءات للتحكم في التدفق!ومن المتوقع في بعض الأحيان الفشل.

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

المحلول

وأنا شخصيا أعتقد أن استخدام نفس الفكرة كما TryParse (): باستخدام المعلمة خارج لإخراج القيمة الحقيقية، وإرجاع منطقية تشير إلى ما إذا كانت الدعوة ناجحة أم لا

وpublic bool CalculatePoint(... out Point result);

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

نصائح أخرى

لماذا فشلوا؟ اذا كان بسبب شيء المتصل قام به (أي الحجج المقدمة) ثم رمي ArgumentException من المناسب تماما. وهناك طريقة محاولة [...] الذي يتجنب باستثناء ما يرام.

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

وثمة بديل آخر هو رمي استثناء. ومع ذلك، عموما يريدون فقط لرمي الاستثناءات في "حالات استثنائية".

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

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

وحتى في صافي وTryParse ديه شقيق تحليل بحيث يمكنك الحصول على استثناء إذا كنت ترغب في ذلك.

إذا كنت وفرت طريقة TrySomething وأود أيضا أن توفر طريقة الأمر الذي ألقى استثناء في حالة الفشل. ثم والامر متروك للطالب.

ونموذج لقد استعملت هو يستخدم نفس MS واحد مع أساليب TryParse من مختلف الطبقات.

ولديك كود الأصلي:
نقطة CalculatePoint الجمهور (... خارج منطقية boSuccess)؛
قائمة CalculateListOfPoints الجمهور (... خارج منطقية boSuccess)؛

هل تتحول إلى CalculatePoint منطقي العام (... من أصل (أو المرجع) نقطة CalculatedValue)؛
CalculateListOfPoints منطقي العام (... من أصل (أو المرجع) قائمة CalculatedValues)؛

وأساسا جعل لكم نجاح / فشل قيمة الإرجاع.

لتلخيص هناك طريقتان يمكنك اتباعهما:

  1. عندما يكون نوع الإرجاع من نوع القيمة، مثل Point، استخدم ميزة Nullable في C# وإرجاع نقطة؟(ويعرف أيضًا باسم Nullable)، وبهذه الطريقة لا يزال بإمكانك إرجاع قيمة فارغة عند الفشل
  2. رمي استثناء عندما يكون هناك فشل.الحجة/المناقشة بأكملها بشأن ما هو "استثنائي" وما هو غير "استثنائي" هي نقطة خلافية، إنها واجهة برمجة التطبيقات (API) الخاصة بك، وعليك أن تقرر ما هو السلوك الاستثنائي.
  3. اعتماد نموذج مشابه لذلك الذي نفذته Microsoft في الأنواع الأساسية مثل Int32، وتوفير CalculatePoint وTryCalculatePoint (int32.Parse وint32.TryParse) والحصول على رمية واحدة وإرجاع منطقي واحد.
  4. قم بإرجاع بنية عامة من أساليبك التي تحتوي على خاصيتين، bool Success وGenericType Value.

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

وهذا يعتمد في الغالب على سلوك أساليب الاتصال واستخداماتها.

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

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

وأحيانا في كلا الاتجاهين منطقية ...

يعود نقطة.فارغة.إنه نمط تصميم .NET لإرجاع حقل خاص عندما تريد التحقق من نجاح إنشاء البنية.يتجنب خارج المعلمات عندما تستطيع.

public static readonly Point Empty

وثمة نمط أنني تجريب بإرجاع <م> ربما . لها دلالات <م> TryParse نمط، ولكن توقيع مماثل للنمط خالية العائد على خطأ.

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

وربما الدرجة تبدو شيئا مثل هذا:

/// <summary>
/// Represents the return value from an operation that might fail
/// </summary>
/// <typeparam name="T"></typeparam>
public struct Maybe<T>
{
    T _value;
    bool _hasValue;


    public Maybe(T value)
    {
        _value = value;
        _hasValue = true;
    }

    public Maybe()
    {
        _hasValue = false;
        _value = default(T);
    }


    public bool Success
    {
        get { return _hasValue; }
    }


    public T Value
    {
        get 
            { // could throw an exception if _hasValue is false
              return _value; 
            }
    }
}

وأود أن أقول أفضل الممارسات هي قيمة الإرجاع تعني النجاح، و<لأ href = "http://www.c-sharpcorner.com/UploadFile/rajeshvs/ExceptionHandlinginCSharp11282005051444AM/ExceptionHandlinginCSharp.aspx" يختلط = "نوفولو noreferrer" > استثناء يعني الفشل.

وأنا لا أرى أي سبب في الأمثلة التي قدمتها التي يجب أن لا تستخدم <لأ href = "http://www.c-sharpcorner.com/UploadFile/rajeshvs/ExceptionHandlinginCSharp11282005051444AM/ExceptionHandlinginCSharp.aspx" يختلط = "نوفولو noreferrer "> استثناءات في حال الفشل.

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

// NB:  A bool is the return value. 
//      This makes it possible to put this beast in if statements.
public bool TryCalculatePoint(... out Point result) { }

public Point CalculatePoint(...)
{
   Point result;
   if(!TryCalculatePoint(... out result))
       throw new BogusPointException();
   return result;
}

وأفضل ما في العالمين!

ووTrySomething منطقي () على الأقل من الناحية العملية، والذي يعمل طيب لأساليب تحليل صافي، ولكن أنا لا أعتقد أنني أحب ذلك بشكل عام.

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

وبالعودة لاغية عندما يكون ذلك ممكنا في معظم الحالات حسنا، عندما كنت لا تريد استثناء.

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

وأنت لا تريد أن تكون رمي الاستثناءات عندما يكون هناك ومن المتوقع يحدث شيء، كما جاءKevin الاستثناءات هي لحالات استثنائية.

ويجب أن تعود شيء أنه من المتوقع ل 'فشل'، لاغية عموما هو خياري العودة سيئة.

وثائق الأسلوب الخاص بك يجب إبلاغ المستخدمين عن ما يمكن توقعه عندما تكون البيانات <م> لا يحسب .

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

وحسنا مع نقطة، يمكنك إرسالها مرة أخرى Point.Empty كقيمة إرجاع في حالة الفشل. الآن كل هذا لا حقا هو العودة إلى نقطة مع 0 لصالح X و Y قيمة، حتى إذا كان هذا يمكن أن يكون قيمة الإرجاع صالحة، وسوف أظل بعيدا عن ذلك، ولكن إذا وطريقتك أبدا بإرجاع (0،0) نقطة ، ثم يمكنك استخدام ذلك.

عذرا، تذكرت للتو نوع قيم الفارغة، يجب أن ننظر في ذلك. ولست متأكدا أيضا ما هو فوق بالرغم من ذلك.

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