سؤال

فقط بدافع الفضول ، طلب هذا

مثل التعبير واحد أدناه

a = (condition) ? x : y; // two outputs

لماذا لا يمكننا أن يكون لدينا مشغل للعوامل؟
قل،

myValue = f ??? fnApple() : fnMango() : fnOrange(); // no. of outputs specified in the enum definition

بدلاً من عبارات التبديل (على الرغم من أن إعادة البناء ممكنة)


enum Fruit
{
    apple,
    mango,
    orange      
};

Fruit f = Fruit.apple;

أم أنه نوع من المشغل عديم الفائدة؟

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

المحلول

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

switch (f)
{
    case Fruit.Apple: myValue = fnApple(); break;
    case Fruit.Mango: myValue = fnMango(); break;
    case Fruit.Orange: myValue = fnOrange(); break;
    default: throw new ArgumentOutOfRangeException("f");
}

بدلاً من ذلك ، قم بإنشاء خريطة:

static readonly Dictionary<Fruit, Func<Foo>> FruitFunctions = 
    new Dictionary<Fruit, Func<Foo>> {
    { Fruit.Apple, fnApple },
    { Fruit.Mango, fnMango },
    { Fruit.Orange, fnOrange }
};
...

myValue = FruitFunctions[f]();

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

نصائح أخرى

في غيرها ، يمكنني التفكير في ثلاثة أسباب:

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

بناء الجملة C# يستعير من C ++ ، و C ++ يستعير بناء جملة من C ، ولم يكن C ???::: المشغل ، لأن K&R ربما لم تشعر أنه كان ضروريًا. إنه ليس "مشغلًا عديم الفائدة" ، ولكن سيعتبر السكر النحوي.

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

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

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

معظم اللغات لديها أنماط البرمجة/التصميم التي تسمح بها وتلك التي يريدون الترويج لها. C# يسمح برمجة حتمية وإجرائية ولكن يعزز استخدام التقنيات الموجهة للكائن. ينتمي مشغلك بحزم في المخيم الأول وليس شيئًا يرغب مصممي اللغة في دعمه.

إذا كنت ترغب في البرمجة بهذا النمط ، فيمكنك استخدام:

    myValue = (f == Fruit.apple) ? fnApple() 
            : (f == Fruit.mango) ? fnMango()
            : fnOrange();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top