2015-12-19 58 views
0
let inline set (x: ^t) = BitConverter.ToUInt32(BitConverter.GetBytes(x),0) 

我試過類似上面的東西,但它不起作用。輸入約束或運行時解析類型也不行。另外,我猜測答案是否定的,但是有可能告訴編譯器泛型類型只是float32或float嗎?這會節省我很多麻煩。如何打電話給Bitconverter.Getbytes通用?

編輯:

我感到意外的是什麼托馬斯Petricek所寫的作品而反向不會:

let inline toUint32 conv x = 
    let bytes = conv x 
    BitConverter.ToUInt32(bytes, 0) 

toUint32 BitConverter.GetBytes 9999.99f 
toUint32 BitConverter.GetBytes 9999.99 

這很有趣。如果沒有其他文章中的conv : BitConvertible,我也無法使其工作。

+2

你究竟想在這裏做什麼? –

+0

試圖弄清楚如何調用一個更大的函數泛型。雖然我想我已經弄清楚了。我本身並不需要'通用',我只是需要它來接受float32或float。 (a:dMatrix <'t>)(beta:'t)(B:dMatrix <'t>)(C:dMatrix <'t>)='這是行不通的。相反,我剛纔發現我可以做的是鍵入alliasing。 (b:dMatrix)(C:dMatrix)='當然,在dMatrix類中,float類型是浮點型float32,然後是內聯型sgeam2 transa(alpha:floatType)類型都是floatType。 –

+0

@MarkoGrdinic編輯你的問題,而不是在評論中放置代碼。另外,這些評論簽名有哪些與OP的關係? –

回答

2

如果您準備做一些有點不尋常的事情,可以使用靜態解析類型約束來推廣該函數。

請注意,這不適用於其他.NET語言 - 靜態解析類型約束完全是F#編譯器的一個功能。

type BitConvertible = 
    |BitConvertible 
    static member Convert (conv : BitConvertible, flt : float) = 
     System.BitConverter.GetBytes(flt) 
    static member Convert (conv : BitConvertible, flt32 : float32) = 
     System.BitConverter.GetBytes(flt32) 

module BitConverter = 
    let inline convertToBytes x = 
     ((^T or ^U) : (static member Convert : ^T * ^U -> byte[]) (BitConvertible, x)) 

然後你可以使用它...

let a = BitConverter.convertToBytes 16.0 
let b = BitConverter.convertToBytes 27.0f 
+0

什麼是'conv:BitConvertible'呢?那純粹是爲了類型推斷嗎?如果沒有它,我似乎無法做到這一點。 –

+0

@MarkoGrdinic是的,如果你可以在'float'或'float32'上定義靜態成員會更容易,但是你不能這樣做,因爲它們是以類型構建的,並且爲了靜態解析的目的不檢查擴展方法類型約束。相反,您可以在其他一些(完全任意)類型上定義函數,在這種情況下爲'BitConvertible'。 – TheInnerLight

+0

@MarkoGrdinic通過接受/提供一個'BitConvertible',您提供了一種將'Convert'功能本地化爲特定類型的方法。以這種方式定義函數的語法非常糟糕。儘管我認爲合法的用途確實存在,但您應該儘可能避免使用這種工具 - 例如,我正在使用它們在我正在開發的GPU庫中定義主機設備陣列轉換。 – TheInnerLight

3

靜態成員的約束不直接讓你寫inline函數,將調用重載方法。編譯器無法決定是否鍵入檢查函數,就好像參數是floatfloat32或任何其他支持的類型。

簡單的解決方案是通過轉換功能作爲一個單獨的參數:

let inline toUint32 x conv = 
    let bytes = conv x 
    BitConverter.ToUInt32(bytes, 0) 

toUint32 9999.99f BitConverter.GetBytes 
toUint32 9999.99 BitConverter.GetBytes 

這一點需要更多的輸入,但它是很容易看到發生了什麼事情。調用者只需要提供一個轉換功能 - 在典型情況下,只需要BitConverter.GetBytes即可。

另一種方法(在其他答案中已經討論過)是使用一個稍微黑客的技巧,可以讓你指定更多花哨的靜態約束;這消除了傳遞顯式函數的需要,只要它對最終用戶是隱藏的,它可以縮短代碼。