Dot-Net
如何密封覆蓋的屬性
假設我有一對明顯做作的 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 的支持存在一些限制,因此您通常不應期望能夠生成與任意 C# 類層次結構相同的 F# 類層次結構。據我所知,沒有辦法覆蓋和密封虛擬方法。
看起來 F# 定義了密封屬性,其 AttributeTargets 屬性設置為僅類,它可能無法密封成員。
這可能沒問題,因為 F# 中的繼承和覆蓋函式通常不如 C# 慣用。如果不重寫更多的 F# 習語,我認為你無法真正得到你想要的東西。從這個開始:
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成員,所有其他類型都使用“基礎”功能。