代码之家  ›  专栏  ›  技术社区  ›  Thorsten Lorenz

我如何在f_中隐藏方法?

  •  5
  • Thorsten Lorenz  · 技术社区  · 16 年前

    我目前正在f_中实现一个spec框架,我想隐藏equals、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
    
        [<EditorBrowsable(EditorBrowsableState.Never)>]
        abstract Equals : (obj) -> bool
    
        [<EditorBrowsable(EditorBrowsableState.Never)>]
        abstract ToString: unit -> string
    
        [<EditorBrowsable(EditorBrowsableState.Never)>]
        abstract GetHashCode: unit -> int
    
        [<EditorBrowsable(EditorBrowsableState.Never)>]
        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 可以通过隐藏 [<NoEquality>] [<NoComparison>] 但这也会改变语义学。

    通过editorbrowable属性隐藏不起作用。

    拥有干净的API并且仍然能够重载方法的唯一方法是使这些方法成员成为静态的。

    通过在我的项目中浏览,可以找到结果类。 FSharpSpec .

    可以找到相关类型 here.

    感谢所有帮助我解决这个问题的人。

    干杯。。。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Tomas Petricek    16 年前

    或者,可以使用模块中包含的函数,使用可选样式设计库。这是通常的写作方式 功能性 用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将显示模块中定义的函数,因此在这种情况下不会看到任何噪声。

        2
  •  5
  •   Brian    16 年前

    重复我的回答

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

    在f中,可以通过用noeQuality和noComparison属性注释类型来禁用equals&gethashcode(并从intellisense中删除它们),如下所示。用户定义的方法也可以通过过时的属性或ishidden=true的compilerMessage属性从IntelliSense列表中隐藏。无法从f_intellisense隐藏System.Object方法getType和toString。

    [<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
    
        3
  •  3
  •   kvb    16 年前

    我认为在一般情况下,没有任何方法可以做到这一点。在特定情况下 .Equals .GetHashCode ,您可以通过将 [<NoEquality>] 属性,但除了隐藏这些方法之外,它实际上还有一个语义效果。

    编辑

    同样值得一提的是,流畅的接口在f_中很少使用,因为使用组合器和流水线更惯用。例如,假设我们想要创建一种创建算术表达式的方法。而不是

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

    我认为大多数F用户更喜欢写

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

    使用这种样式,不需要隐藏成员,因为表达式通过管道传递到组合器,而不是调用表达式生成器的方法。