假设我有一对明显设计的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显然无法应用于成员。 当然,我可以密封整个班级,从而密封所有成员,但是(这是非常重要但是)我的目标是匹配现有的班级签名完全< / strong>并且基类具有其他虚拟/抽象成员,理想情况下应该保持可覆盖。
答案 0 :(得分:5)
看起来F#定义了Sealed Attribute的定义,其AttributeTargets属性设置为Class,它可能无法密封成员。
这可能是 ok ,因为继承和覆盖函数在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
成员,所有其他类型都使用“基本”功能。
答案 1 :(得分:3)
目前F#支持OO存在一些限制,因此通常不应期望能够生成与任意C#类层次结构相同的F#类层次结构。据我所知,没有办法覆盖和密封虚拟方法。