F#:我如何模式匹配类型值?

时间:2011-04-28 03:58:42

标签: generics f# types pattern-matching

我有一个带泛型参数的函数,在其中我需要执行两个函数中的一个,具体取决于参数的类型。

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通知我,通配符案例永远不会被执行,因为我显然在编译时获得了泛型的类型,而不是运行时的实际类型。我该怎么做?

3 个答案:

答案 0 :(得分:13)

在您的代码中,第一个模式匹配规则不会比较typeof&lt;'T&gt;反对hhType。相反,它将引入一个名为hhType的新值。这就是你得到警告的原因。 我宁愿修改这样的代码。

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

答案 1 :(得分:2)

_path'T的实例吗?如果是这样,Talljoe的解决方案将起作用,否则你将不得不做类似的事情:

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

错误的原因是hhType表达式中的match影响了hhType的先前声明。因此,它只是将匹配表达式的值捕获到新绑定中。这匹配所有内容,因此您的通配符条件永远不会被命中。

答案 2 :(得分: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;
}

不确定为什么编译器这样做:(。任何人都可以描述这种行为吗?