Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#使用不同的模板参数实现接口_F# - Fatal编程技术网

F#使用不同的模板参数实现接口

F#使用不同的模板参数实现接口,f#,F#,有此代码: type Point2D(x, y) = member this.X with get() = x member this.Y with get() = y interface System.IEquatable<Point2D> with member x.Equals point = x.X = point.X && x.Y = point.Y type Poi

有此代码:

type Point2D(x, y) =
    member this.X with get() = x
    member this.Y with get() = y

    interface System.IEquatable<Point2D> with
        member x.Equals point =
            x.X = point.X
            && x.Y = point.Y

type Point3D(x, y, z) =
    inherit Point2D(x, y)

    member this.Z with get() = z

    interface System.IEquatable<Point3D> with
        member x.Equals point =
            (x :> System.IEquatable<Point2D>).Equals point
            && x.Z = point.Z
输入Point2D(x,y)=
使用get()=X作为该.X的成员
使用get()=Y成员this.Y
接口System.i可与
成员x等于点=
x、 x=点x
&&x.Y=点Y
输入Point3D(x、y、z)=
继承点2D(x,y)
使用get()=Z作为该.Z的成员
接口System.i可与
成员x等于点=
(x:>System.IEquatable)。等于点
&&x.Z=点.Z


我有编译时间。不允许使用不同的模板参数实现同一接口。但我想在派生类型中实现强类型等于。那么我应该怎么处理它呢?

正如编译器错误所解释的,这是不受支持的,因此最好的解决方案可能是在这种情况下避免继承,并添加一个成员以转换为二维点:

type Point3D(x, y, z) =
        member this.X with get() = x
        member this.Y with get() = y
        member this.Z with get() = z

        member this.As2D = new Point2D(this.X, this.Y)

        interface System.IEquatable<Point3D> with
            member x.Equals point =
                x.X = point.X && x.Y = point.Y && x.Z = point.Z
输入Point3D(x,y,z)=
使用get()=X作为该.X的成员
使用get()=Y成员this.Y
使用get()=Z作为该.Z的成员
成员this.As2D=新点2d(this.X,this.Y)
接口System.i可与
成员x等于点=
x、 x=点.x&&x.Y=点.Y&&x.Z=点.Z

不行。这有点令人遗憾,因为F#可以很好地使用来自不同CLR语言的具有这种设计的类型

我听到的解释是,拥有这样一个特性并不重要,部分原因是拥有这样一个重类/重接口的设计不被认为是惯用的(我同意)

因此,您可以选择在C#中实现这些类型

另一种更惯用的方法是将它们实现为记录:

type Point2D = { x: float; y: float }

type Point3D = { x: float; y: float; z: float }
    with 
        static member FromPoint2D (p: Point2D) = ...
        member this.ToPoint2D () = ...

也许可以添加一个模块,该模块具有比较2d和3d的功能,可以为您封装转换。

作为F#提示,在最新版本的F#中,此版本的F#不允许这样做。你打算从C#中使用它,还是只针对F#?我认为这正是一种无害的特性,可以很好地实现,因为该语言已经对拉式请求开放。