我可以为两个我不直接控制的类添加隐式转换吗?

Car*_*ers 16 c# extension-methods f# operator-overloading implicit-conversion

我希望能够在两个不相容的类之间隐式转换.

其中一个类是Microsoft.Xna.Framework.Vector3,而另一个Vector类只是F#项目中使用的类.我正在使用XNA在C#中编写一个3D游戏,并且 - 虽然它是用3D绘制的,但游戏只在两个维度上进行(它是鸟瞰图).F#类使用2D矢量来处理物理:

type Vector<'t when 't :> SuperUnit<'t>> =
    | Cartesian of 't * 't
    | Polar of 't * float
    member this.magnitude =
        match this with
        | Cartesian(x, y) -> x.newValue(sqrt (x.units ** 2.0 + y.units ** 2.0))
        | Polar(m, _) -> m.newValue(m.units)
    member this.direction =
        match this with
        | Cartesian(x, y) -> tan(y.units / x.units)
        | Polar(_, d) -> d
    member this.x =
        match this with
        | Cartesian(x, _) -> x
        | Polar(m, d) -> m.newValue(m.units * cos(d))
    member this.y =
        match this with
        | Cartesian(_, y) -> y
        | Polar(m, d) -> m.newValue(m.units * sin(d))
Run Code Online (Sandbox Code Playgroud)

此向量类使用物理项目使用的单位系统,该系统采用原生F#度量单位并将它们组合在一起(距离,时间,质量等单位).

但XNA使用自己的Vector3类.我想从F#添加的隐式转换Vector到XNA Vector3这需要照顾的两个维度的游戏发生在,该轴是"向上"等,这会是简单的,只是Vector v -> new Vector3(v.x, v.y, 0)什么的.

我无法弄清楚如何做到这一点.我无法在F#中添加隐式转换,因为类型系统(正确)不允许它.我无法将它添加到Vector3类,因为它是XNA库的一部分.据我所知,我不能使用扩展方法:

class CsToFs
{
    public static implicit operator Vector3(this Vector<Distance> v)
    {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

this关键字的错误,和

class CsToFs
{
    public static implicit operator Vector3(Vector<Distance> v)
    {
        return new Vector3((float)v.x.units, (float)v.y.units, 0);
    }

    public static void test()
    {
        var v = Vector<Distance>.NewCartesian(Distance.Meters(0), Distance.Meters(0));
        Vector3 a;
        a = v;
    }
}
Run Code Online (Sandbox Code Playgroud)

是一个错误a = v;(不能隐式转换...).

有没有办法做到这一点,而不能把演员阵容放在任何一个类?作为最后的手段,我可​​以open Microsoft.Xna.Framework在F#中进行转换,但这对我来说似乎不对 - 物理库不应该知道或关心我用来编写游戏的框架.

Fem*_*ref 15

不,你不能.必须将隐式运算符定义为其中一个类的成员.但是,您可以定义扩展方法(您的示例不起作用,因为扩展方法必须在a中public static class).

public static class ConverterExtensions
{
    public static Vector ToVector (this Vector3 input)
    {
      //convert
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 今天看到这个评论,决定尝试一下。不,这不起作用。我认为该语言最多只进行 1 次转换。如果您显式转换为中间类型,那么它会起作用,但此时您最好只编写扩展方法。 (4认同)