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

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

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

 type Vector SuperUnit> = | 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)) 

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

但XNA使用自己的Vector3类。 我想添加一个从F# Vector到XNA Vector3的隐式转换,它负责Vector3游戏中发生的两个维度,哪个轴是“向上”等等。它很简单,只是Vector v -> new Vector3(vx, vy, 0)或其他什么。

我不知道怎么做。 我无法在F#中添加隐式转换,因为类型系统(正确)不允许它。 我无法将其添加到Vector3类,因为它是XNA库的一部分。 据我所知,我不能使用扩展方法:

 class CsToFs { public static implicit operator Vector3(this Vector v) { //... } } 

this关键字是一个错误,和

 class CsToFs { public static implicit operator Vector3(Vector v) { return new Vector3((float)vxunits, (float)vyunits, 0); } public static void test() { var v = Vector.NewCartesian(Distance.Meters(0), Distance.Meters(0)); Vector3 a; a = v; } } 

a = v;的错误a = v; (不能隐含地转换……)。

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

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

 public static class ConverterExtensions { public static Vector ToVector (this Vector3 input) { //convert } } 

在C#中你不能。 您可以提供具有额外转换的后代类型(假设类型未密封); 或者您可以提供一个通用的包装类,以某种方式添加转换。

所有这些的便利性取决于这些包装/适配可以与原始API一起使用的方式。

另一方面,我看到你也在使用F#。 IIRC F#应该具有一定程度的元编程能力(如.NET的许多函数语言,如Boo和Nemerle)。 如果可以在这里使用它,我不会感到惊讶。 不幸的是,我的F不足以帮助那里