10

我希望能夠隱式轉換兩個不兼容的類。我可以爲兩個不直接控制的類添加隱式轉換嗎?

其中一個類是Microsoft.Xna.Framework.Vector3,另一個類只是在F#項目中使用的Vector類。我正在用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)) 

該載體類利用由物理項目,這需要測量的天然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) 
    { 
     //... 
    } 
} 

是在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; 
    } 
} 

a = v;錯誤(不能隱式轉換... )。

有沒有辦法做到這一點,而無法將劇組放在任何一個類中?作爲最後的手段,我可​​以open Microsoft.Xna.Framework並在F#中進行轉換,但這對我來說似乎是錯誤的 - 物理庫不應該知道或關心我用什麼框架編寫遊戲。

回答

10

不,你不能。隱式運算符必須被定義爲其中一個類的成員。但是,您可以定義一個擴展方法(由於擴展方法必須位於public static class中,因此您的示例不起作用)。

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

不能相信我沒有想到這個,即使它幾乎正是我想要的。 – 2011-04-02 23:46:31

2

在C#中你不行。你可以提供具有額外轉換的後代類型(前提是這些類型不是密封的);或者你可以提供一個通用的包裝類,以某種方式添加轉換。

所有這些的便利取決於這些包裝/改編可以與原始API一起使用的方式。

在另一個說明我看你也在使用F#。 IIRC F#應該具有一定的元編程能力(就像許多.NET的函數式語言一樣,比如Boo和Nemerle)。如果可以在這裏使用它,我不會感到驚訝。不幸的是我的F不夠銳利,無法幫到那裏

+0

我一直在想使用一個子類,我很擔心它會得到過於錯綜複雜,雖然 – 2011-04-02 23:49:34

+0

看到,因爲這兩個對象是值類型 - 我認爲一個子類是出了問題。 – MattDavey 2012-03-23 15:30:32

+2

我試圖使用代理類來隱式轉換,但C#不會自動應用雙重轉換。 (爲什麼構造函數不考慮轉換操作符?) – NetMage 2016-10-06 16:20:44

相關問題