سؤال

لنفترض أن لدي زوجًا من فصول C# مفتعلة بشكل واضح مثل هذا:

public abstract class Foo {
    public abstract int[] LegalValues { get; }
    public virtual bool IsValueLegal(int val) {
        return Array.IndexOf(LegalValues, val) >= 0;
    }
}

وهذا:

public class Bar : Foo {
    static int[] _legalValues = new int[] { 0, 1 }; // whatever
    public sealed override int[] LegalValues 
        { get { return _legalValues; } }
    public sealed override bool IsValueLegal(int val)
        { return base.IsValueLegal(val); }
}

كيف أفعل هذا في F#؟ الرمز الواضح للخصائص:

[<Sealed>]
override this.LegalValues with get() = // ...

[<Sealed>]
override this.IsValueLegal value = // ...

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

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

المحلول

يوجد حاليًا العديد من القيود على دعم F# لـ OO ، لذلك لا ينبغي أن تتوقع عمومًا أن تكون قادرًا على إنتاج تسلسل هرمي فئة F# وهو مطابق لتسلسل هرمي تعسفي C#. على حد علمي ، لا توجد طريقة لتجاوز وإغلاق طريقة افتراضية.

نصائح أخرى

يبدو أن f# يحدد سمة مختومة يتم تعريفه باستخدام خاصية AttributeTargets الخاصة به على الفصل فقط ، وربما لا يمكن إغلاق الأعضاء.

هذا ربما موافق, ، نظرًا لأن الوراثة والوظائف الغالبة تكون بشكل عام أقل من ذكاءات F# من C#. لا أعتقد أنه يمكنك حقًا الحصول على ما تريد دون إعادة الكتابة في المزيد من التعابير. ابدأ بهذا:

type foo =
    | Bar
    | Baz
    | Qux
        with
            member this.LegalValues =
                match this with
                | Bar -> [0; 1]
                | Qux -> [-1; 0; 1]
                | Baz -> [0 .. 10 ]
            member this.IsValueLegal value =
                match this with
                | Baz -> value >= 0 && value <= 10
                | _ -> List.exists (fun x -> x = value) (this.LegalValues)

تستطيع قول ذلك Baz "تجاوز" foo.IsValueLegal عضو ، جميع الأنواع الأخرى تستخدم وظيفة "القاعدة".

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