Как я могу скрыть методы в F#?

Я в настоящее время реализую платформу Спецификации в F#, и я хочу скрыть Равняние, GetHashCode и т.д. методы на моем should введите, так, чтобы API не был нарушен ими.

Я знаю в C#, он сделан, заставив класс реализовать интерфейс как это:

using System;
using System.ComponentModel;

public interface IFluentInterface
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    bool Equals(object other);

    [EditorBrowsable(EditorBrowsableState.Never)]
    string ToString();

    [EditorBrowsable(EditorBrowsableState.Never)]
    int GetHashCode();

    [EditorBrowsable(EditorBrowsableState.Never)]
    Type GetType();
}

Я пытался делать то же в F#:

type IFluentInterface = interface

    []
    abstract Equals : (obj) -> bool

    []
    abstract ToString: unit -> string

    []
    abstract GetHashCode: unit -> int

    []
    abstract GetType : unit -> Type 
end

Реализованный это в моем типе:

        interface IFluentInterface with
        member x.Equals(other) = x.Equals(other)
        member x.ToString()    = x.ToString() 
        member x.GetHashCode() = x.GetHashCode()
        member x.GetType()     = x.GetType() 

но без успеха.

Я также пытался переопределить методы в своем типе и добавлении атрибута тот путь, но это не добивалось цели также.

Таким образом, вопрос остается, как я могу очистить свой API?

Править:

Благодаря справке (см. ниже) я смог решить свою проблему.

Таким образом, .Equals и .GetHashCode может быть скрыт через [] [] но это также изменит семантику.

Сокрытие через атрибуты EditorBrowsable не работает.

Единственный способ иметь чистый API и все еще смочь перегрузить методы состоит в том, чтобы сделать этих участников метода статичными.

Получающийся класс может быть найден путем просмотра в моем FSharpSpec проекта.

Рассматриваемый тип может быть найден здесь.

Благодаря всем, кто помог мне решить эту проблему.

Аплодисменты...

5
задан Greg 4 January 2011 в 21:10
поделиться

3 ответа

В качестве альтернативы вы можете разработать библиотеку, используя альтернативный стиль, используя функции, заключенные в модуль. Это обычный способ написания функционального кода на F #, и тогда вам не нужно будет скрывать какие-либо стандартные методы .NET. Чтобы завершить пример, приведенный «kvb», вот пример объектно-ориентированного решения:

type MyNum(n:int) =
  member x.Add(m) = MyNum(n+m)
  member x.Mul(m) = MyNum(n*m)

let n = new MyNum(1)
n.Add(2).Mul(10) // 'ToString' shows in the IntelliSense

Функциональный способ написания кода может выглядеть следующим образом:

type Num = Num of int
module MyNum =
  let create n = Num n
  let add m (Num n) = Num (m + n)
  let mul m (Num n) = Num (m * n)

MyNum.create 1 |> MyNum.add 2 |> MyNum.mul 10

Если вы наберете MyNum. , F # IntelliSense покажет функции, определенные в модуле, поэтому в этом случае вы не увидите никакого шума.

4
ответ дан 13 December 2019 в 05:34
поделиться

Повторяю свой ответ от

http://cs.hubfs.net/forums/thread/13317.aspx

В F# вы можете запретить Equals и GetHashCode (и удалить их из intellisense), аннотировав тип атрибутами NoEquality и NoComparison, как показано ниже. Определяемые пользователем методы также можно скрыть из списка intellisense с помощью атрибута Obsolete или атрибута CompilerMessage с IsHidden=true. Не существует способа скрыть методы System.Object GetType и ToString из интенсива F#.

[<NoEquality; NoComparison>]
type Foo() =
    member x.Bar() = ()
    member x.Qux() = ()
    [<System.Obsolete>]
    member x.HideMe() = ()
    [<CompilerMessage("A warning message",99999,IsError=false,IsHidden=true)>]
    member x.WarnMe() = ()

let foo = new Foo()
foo.  // see intellisense here
5
ответ дан 13 December 2019 в 05:34
поделиться

Я не думаю, что это вообще есть в F #. В конкретном случае .Equals и .GetHashCode вы можете сделать их непригодными для использования, поместив атрибут [] в свой тип, но на самом деле это помимо скрытия этих методов имеет семантический эффект.

РЕДАКТИРОВАТЬ

Также стоит упомянуть, что свободные интерфейсы редко используются в F #, поскольку гораздо более идиоматично использовать вместо них комбинаторы и конвейерную обработку. Например, представьте, что мы хотим создать способ создания арифметических выражений. Я думаю, что большинство пользователей F # предпочли бы писать не

let x = Expressions.MakeExpr(1).Add(2).Mul(3).Add(4)

, а

open Expressions
let x = 
  1
  |> makeExpr
  |> add 2
  |> mul 3
  |> add 4

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

3
ответ дан 13 December 2019 в 05:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: