Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to seal an overridden property

Suppose I have a pair of obviously contrived C# classes like this:

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

and this:

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); }
}

How do I do this in F#? The obvious code for the properties:

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

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

Triggers an error because the SealedAttribute apparently can't be applied to members. I can, of course, seal the entire class and thereby seal all members, but (and this is a really important but) is that I have a goal of matching an existing class signature exactly and the base class has other virtual/abstract members that should, ideally, remain overridable.

like image 454
plinth Avatar asked Dec 02 '10 20:12

plinth


People also ask

Can I override a property?

Property overriding means redefining or modifying the property of the base class in its derived class. Thus, it can be only achieved in inheritance. The property that needs to be overridden should be open in nature, in the base class. We cannot override a method that is final in nature.

Can we override sealed class?

If you create a sealed class, it cannot be derived. If you create a sealed method, it cannot be overridden.

How do you override a base class property?

You can also modify the behavior of the base class properties and methods used by the derived class. This is called property overriding and method overriding. You override a base class property by redefining a property in the derived class. You override a method by redefining a sub or function in the derived class.

What is the use of the sealed modifier?

When applied to a class, the sealed modifier prevents other classes from inheriting from it. In the following example, class B inherits from class A , but no class can inherit from class B . You can also use the sealed modifier on a method or property that overrides a virtual method or property in a base class.


2 Answers

Looks like F# defines the Sealed Attribute is defined with its AttributeTargets property set to Class only, its probably not possible to seal members.

This is probably ok, since inheritance and overriding functions is generally less idiomatic in F# than C#. I don't think you can really get what you want without rewriting in more F# idioms. Start with this:

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)

You can say that Baz "overrides" the foo.IsValueLegal member, all other types use the "base" function.

like image 129
Juliet Avatar answered Sep 22 '22 19:09

Juliet


There are currently several limitations to F#'s support for OO, so you should not generally expect to be able to produce an F# class hierarchy which is identical to an arbitrary C# class hierarchy. As far as I know, there is no way to override and seal a virtual method.

like image 28
kvb Avatar answered Sep 24 '22 19:09

kvb