Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 实现接口的非泛型方法中泛型的模式匹配_F#_Pattern Matching - Fatal编程技术网

F# 实现接口的非泛型方法中泛型的模式匹配

F# 实现接口的非泛型方法中泛型的模式匹配,f#,pattern-matching,F#,Pattern Matching,我有一个令人沮丧的问题。我正在ASP.NETMVC中构建一个应用程序,并正在实现IViewEngine接口。在其中一个方法中,我试图动态地确定视图结果的类型。有时结果是一个模板(类型为template->。。。 有什么想法吗?不幸的是,没有办法很好地做到这一点。如果您可以控制模板类型,那么您只需检查界面: | :? ITemplate as t -> ... 如果不是这样,那么你唯一的选择就是使用一些反射魔法。你可以实现一个活动模式,当类型是某个模板时匹配(arg:Template您能

我有一个令人沮丧的问题。我正在ASP.NETMVC中构建一个应用程序,并正在实现IViewEngine接口。在其中一个方法中,我试图动态地确定视图结果的类型。有时结果是一个模板(类型为template->。。。
有什么想法吗?

不幸的是,没有办法很好地做到这一点。如果您可以控制
模板
类型,那么您只需检查界面:

| :? ITemplate as t -> ...

如果不是这样,那么你唯一的选择就是使用一些反射魔法。你可以实现一个活动模式,当类型是某个
模板时匹配(arg:Template您能根据它使用的
键的类型使整个视图引擎类通用吗?Indivudual项目需要从视图引擎类继承,并在过程中指定键的类型。

我喜欢这种方法,但您可以通过基于基因参数化活动模式,使其更通用一些要匹配的ric类型定义。请参阅。@kvb:Nice trick!我尝试编写泛型活动模式,但似乎无法在用法中指定类型参数。使用引号似乎效果很好(或者参数可能只是
(typedefof)
?),模式中只允许有限的语言元素子集(即使对于激活图案的参数也是如此),所以我不认为您可以直接传递类型。据我所知,使用引号是该语言允许的最干净的解决方案,但我希望被证明是错误的!好主意!虽然在这种情况下,我不需要巫毒。无论如何,谢谢!我感谢所有的努力。这最终证明是一个非常好的主意It’很简单!我照你说的做了,在Global.asax.cs中添加了这一行:ViewEngines.Engines.Add(new WingBeats.Mvc.WingBeatsTemplateEngine());谢谢!(我觉得自己没有想出这个解决方案有点愚蠢,尽管我为此奋斗了好几个小时!)
   match result with
   | :? foo -> ...
   | :? bar -> ...
   | :? Template<'a> -> ...
| :? ITemplate as t -> ...
let (|GenericTemplate|_|) l =
  let lty = typeof<list<int>>.GetGenericTypeDefinition()
  let aty = l.GetType()
  if aty.IsGenericType && aty.GetGenericTypeDefinition() = lty then
    Some(aty.GetGenericArguments())
  else 
    None
match result with
| GenericTemplate tys ->
    // ...
 type TemplateHandler =
   static member Handle<'T>(arg:Template<'T>) =
     // This is a standard generic method that will be 
     // called from the pattern matching - you can write generic
     // body of the case here...
     "aaa"

| :? GenericTemplate tys ->
    // Invoke generic method dynamically using reflection
    let gmet = typeof<TemplateHandler>.GetMethod("Handle").MakeGenericMethod(tys)
    gmet.Invoke(null, [| result |]) :?> string // Cast the result to some type