Как запечатать переопределенную собственность - PullRequest
9 голосов
/ 02 декабря 2010

Предположим, у меня есть пара явно искусственных классов 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, очевидно, не может быть применен к элементам.Я, конечно, могу запечатать весь класс и тем самым запечатать всех членов, но (и это действительно важно , но) заключается в том, что у меня есть цель сопоставить существующую сигнатуру класса точно а базовый класс имеет другие виртуальные / абстрактные члены, которые в идеале должны оставаться переопределенными.

Ответы [ 2 ]

5 голосов
/ 03 декабря 2010

Похоже, что 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, все другие типы используют функцию "base".

3 голосов
/ 03 декабря 2010

В настоящее время существует несколько ограничений для поддержки ОО для F #, поэтому вы не должны ожидать, что сможете создать иерархию классов F #, которая идентична произвольной иерархии классов С #.Насколько я знаю, нет способа переопределить и запечатать виртуальный метод.

...