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#?我认为这正是一种无害的特性,可以很好地实现,因为该语言已经对拉式请求开放。