如何在 F# 中隐藏方法? [英] How can I hide methods in F#?

查看:30
本文介绍了如何在 F# 中隐藏方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在 F# 中实现一个 Spec 框架,我想在我的 should 类型上隐藏 Equals、GetHashCode 等方法,这样 API 就不会被这些弄乱.

I am currently implementing a Spec framework in F# and I want to hide the Equals, GetHashCode etc. methods on my should type, so that the API is not cluttered with these.

我知道在 C# 中它是通过让类实现这样的接口来完成的:

I know in C# it is done by making the class implement an interface like this:

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# 中做同样的事情:

I tried doing the same in 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() 

但没有成功.

我还尝试覆盖我的类型中的方法并以这种方式添加属性,但这也没有奏效.

I also tried to override the methods in my type and adding the attribute that way, but that didn't do the trick either.

所以问题仍然存在,我该如何清理我的 API?

So the question remains, how can I clean up my API ?

多亏了帮助(见下文),我才能够解决我的问题.

Thanks to the help (see below) I was able to solve my problem.

总而言之,.Equals.GetHashCode 可以通过 [] 隐藏 [;] 但这也会改变语义.

In summary, .Equals and .GetHashCode can be hidden via [<NoEquality>] [<NoComparison>] but that will also change the semantics.

通过 EditorBrowsable 属性隐藏不起作用.

The hiding via EditorBrowsable attributes does not work.

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

The only way to have a clean API and still be able to overload methods is to make these method members static.

可以通过浏览我的项目FSharpSpec来找到生成的类.

The resulting class can be found by browsing inside my project FSharpSpec.

可以在此处找到相关类型.

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

Thanks to everyone who helped me solve this problem.

干杯...

推荐答案

或者,您可以使用包含在模块中的函数使用替代样式来设计库.这是在 F# 中编写功能代码的常用方法,然后您就不需要隐藏任何标准的 .NET 方法.为了完成'kvb'给出的例子,这里是一个面向对象解决方案的例子:

Alternatively, you could design the library using an alternative style using functions enclosed in a module. This is the usual way for writing functional code in F# and then you won't need to hide any standard .NET methods. To complete the example given by 'kvb', here is an example of object-oriented solution:

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

编写代码的功能方式可能如下所示:

The functional way of writing the code might look like this:

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 将显示模块中定义的函数,因此在这种情况下您不会看到任何噪音.

If you type MyNum., the F# IntelliSense will show the functions defined in the module, so you won't see any noise in this case.

这篇关于如何在 F# 中隐藏方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆