2011-04-28 40 views
9

我有一個函數,它需要一個通用參數,並且在其中我需要根據參數的類型執行兩個函數中的一個。F#:我如何模式匹配類型值?

member this.Load<'T> _path = 
    let hhType = typeof<HooHah> 
    match typeof<'T> with 
     | hhType -> this.LoadLikeCrazy<'T> _path 
     | _ -> this.LoadWithPizzaz<'T> _path 

....其中LoadLikeCrazy和LoadWithPizzaz都返回一個'T.

VS告訴我,通配符的情況永遠不會被執行,因爲我顯然是在編譯時獲得泛型的類型,而不是運行時的實際類型。我如何去做這件事?

回答

13

在您的代碼中,第一個模式匹配規則不會比較type of <'T>與hhType。相反,它會引入一個名爲hhType的新值。這就是你得到警告的原因。 我寧願修改這樣的代碼。

member this.Load<'T> _path =   
    match typeof<'T> with   
    | x when x = typeof<HooHah> -> this.LoadLikeCrazy<'T> _path   
    | _ -> this.LoadWithPizzaz<'T> _path 
+0

甜,感謝nyinyithann! – MiloDC 2011-04-28 07:45:52

2

_path'T的實例嗎?如果是這樣,Talljoe的解決方案將工作,否則你就必須做一些事情,如:

member this.Load<'T> _path = 
    if typeof<'T> = typeof<HooHah> then this.LoadLikeCrazy<'T> _path 
    else this.LoadWithPizzaz<'T> _path 

的原因錯誤是你的match表達式中hhType被遮蔽的hhType事先聲明。所以,它只是將匹配表達式的值捕獲到一個新綁定中。這匹配一切,因此你的通配條件將永遠不會被打。

0

nyinyithann提到的是正確的。我在F#中編寫了下面的代碼:

let Hello name = 
let n = "Sample" 
match name with 
| n -> 1 
| _ -> 0 

得到了同樣的警告。二手反射器,看看有什麼代碼生成,發現下面的代碼(在C#反編譯)

public static int Hello<a>(a name) 
{ 
    a local = name; 
    a name = local; 
    return 1; 
} 

不知道爲什麼編譯器這樣做:(。任何人都可以形容這種行爲?

+0

什麼行爲是你期望從你的代碼嗎?你匹配的名稱比如ie(匹配名稱),然後你提供了兩種選擇,在第一個規則中你創建一個新的變量綁定,也稱爲「名稱」,然後返回0。沒有指定任何模式,或者當守護第一條規則時總是匹配,這意味着第二條規則是多餘的。你究竟想要達到什麼目的? – Robert 2011-04-28 05:33:41

+0

我已經更新了代碼..實際上第一種模式是: n - > 1 ...雖然看起來在匹配塊內定義的「名稱」(變量) - 在本例中爲「n」 - 具有其自己的作用域,並且與匹配塊之前完成的綁定無關 – Ankur 2011-04-28 06:03:25

+1

可以使用Literal屬性獲得您要查找的行爲,Chris Smith有更多詳細信息:http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal- attribute.aspx – Robert 2011-04-28 07:07:47