Вопрос

Предположим, у меня есть пара явно надуманных 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); }
}

Как мне это сделать в #? Очевидный код для свойств:

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

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

Запускает ошибку, поскольку герметичныйattribute, по-видимому, не может быть применен к членам. Конечно, я могу запечатать весь класс и тем самым запечатать всех членов, но (и это Действительно важно Но) в том, что у меня есть цель соответствовать существующей подписи класса точно И базовый класс имеет другие виртуальные / абстрактные члены, которые должны быть, в идеале, остаются переопределенными.

Это было полезно?

Решение

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

Другие советы

Похоже, F # определяет Герметичный атрибут Определяется своим свойством атрибутетаргет, установленным только на класс, его, вероятно, невозможно уплотнить членов.

Это, вероятно 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 Участник, все остальные типы используют функцию «базы».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top