Dot-Net

如何密封覆蓋的屬性

  • January 16, 2017

假設我有一對明顯做作的 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成員,所有其他類型都使用“基礎”功能。

引用自:https://stackoverflow.com/questions/4339657