سؤال

آه ، ألا تحب فقط سوء المعاملة الثلاثية؟ :) فكر في التعبير التالي:

true ? true : true ? false : false

بالنسبة لأولئك منكم الذين يشعرون الآن بالحيرة تمامًا ، يمكنني أن أخبرك أن هذا يقييم حقيقي. بمعنى آخر ، إنه يعادل هذا:

true ? true : (true ? false : false)

ولكن هل هذا موثوق؟ هل يمكنني التأكد من أنه في بعض الظروف لن يأتي إلى هذا:

(true ? true : true) ? false : false

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

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

obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
obj1.Prop4.CompareTo(obj2.Prop4)

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

إذن - هل هذا محدد في أي مكان؟ لم أستطع العثور عليه.

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

المحلول

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

القسم ذي الصلة في ECMA-334 (المعيار C#) هو 14.13 §3:

المشغل الشرطي هو اليمين ، مما يعني أن العمليات يتم تجميعها من اليمين إلى اليسار. [مثال: تعبير عن النموذج a ? b : c ? d : e يتم تقييمه على النحو a ? b : (c ? d : e). مثال نهاية

نصائح أخرى

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

إعادة: "حاول أن تكتب كل شيء بأقواس."

result = (obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
         (obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
         (obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
                                     obj1.Prop4.CompareTo(obj2.Prop4))))

توضيح:

  • "لو أنت يجب أن تسأل ، لا ".
  • "أي شخص يقرأ لك الشفرة..."

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

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

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

نقطة أخيرة للتفكير ، إذا كان بعض الكود الخاص بك يبدو ذكيًا بالنسبة لك:

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

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

obj1.Prop1 != obj2.Prop1
     ? obj1.Prop1.CompareTo(obj2.Prop1)
     : obj1.Prop2 != obj2.Prop2
           ? obj1.Prop2.CompareTo(obj2.Prop2)
           : obj1.Prop3 != obj2.Prop3
                  ? obj1.Prop3.CompareTo(obj2.Prop3)
                  : obj1.Prop4.CompareTo(obj2.Prop4);

الرجوع إلى MSDN:http://msdn.microsoft.com/en-us/library/ty67wk28٪28vs.80٪29.aspx

"إذا كانت الحالة صحيحة ، يتم تقييم التعبير الأول وتصبح النتيجة ؛ إذا كان خطأ ، يتم تقييم التعبير الثاني ويصبح النتيجة. يتم تقييم واحد فقط من تعبيرين على الإطلاق."

x = cond1 ? result1
  : cond2 ? result2
  : cond3 ? result3
  : defaultResult;

ضد

if (cond1) x = result1;
else if (cond2) x = result2;
else if (cond3) x = result3;
else x = defaultResult;

أنا أحب أول واحد.

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

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