带有重载方法的F #Expr.TryGetReflectedDefinition

时间:2014-09-07 11:07:36

标签: reflection f# funscript

我正在为FunScript项目编写一些扩展(F#到Javascript编译器)。如果您有兴趣,可以找到来源here

我试图通过Tomas Petricek模拟AwaitObservable扩展。但是,如果我使用像AwaitObservable(w), AwaitObservable(w1,w2)...这样的重载方法,当我尝试将项目编译为Javascript时会出现以下错误:

An unhandled exception of type 'System.Reflection.AmbiguousMatchException' occurred in FSharp.Core.dll

Additional information: Ambiguous match found.

FunScript在项目中保留反映定义的缓存字典,并在尝试使用Expr.TryGetReflectedDefinition向缓存添加新缓存时发生此错误。如果我使用不同的名称而不是重载(AwaitObservable2, AwaitObservable3...),则错误消失。这是我现在使用的解决方法,但我想了解更多有关该问题以及是否可以修复它以便扩展的用户可以正常使用重载方法。

我可以想象F#中的Reflected Definitions不支持重载方法,也不能仅通过参数的数量来区分方法(我无法检查,因为我没有找到Expr.TryGetReflectedDefinition的实现fsharp GitHub源码库)。但是,让我感到困惑的是,在查找AwaitObservable但是以下方法时不会发生错误:

  

{System.IDisposable的   System-IObservable 1-Subscribe(System.IObserver 1 [FunScript.TypeScript.MouseEvent])} System.Reflection.MethodBase   {System.Reflection.RuntimeMethodInfo}

所以我的问题是:

  1. 为什么Expr.TryGetReflectedDefinitionIObservable.Subscribe而非Async.AwaitObservable失败?
  2. 为什么Expr.TryGetReflectedDefinition抛出异常而不是返回None?
  3. 这是F#反射定义的错误还是不可避免的限制?有可能解决它吗?
  4. 非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

好吧,这似乎没有简单的答案,所以我会尝试回答我自己的问题。经过进一步调查......

  1. 似乎由于Async.AwaitObservable重载存储的反射定义不知何故(这种'某种方式'仍然是无法解释的)失去了实现IObservable的类型的跟踪,这就是为什么他们不知道哪个应使用Subscribe的实施。
  2. 我想这是预期的行为:返回None表示尚未找到反射定义,但这里存在模糊匹配,因此情况不同。
  3. 我还不知道这是一个错误还是一个“功能”,但无论如何我使用CompiledName属性修复了这个特殊情况下的问题,并为每个重载提供了不同的名称。现在一切正常:)
  4. 我希望下次发布一个可以实际回答的问题;)感谢所有花时间阅读此内容的人。