当类型从传递依赖中泄漏时,发布构建失败,Debug很好

时间:2016-09-21 17:11:12

标签: f#

我试图解释有关传递依赖关系的Release和Debug配置之间奇怪的F#编译器行为。我将在这里使用Newtonsoft.Json包作为基本依赖项,因为这是我设法找到问题所能达到的最远的,并且它使示例不那么抽象。

让我们创建一个名为SerializerProject的库项​​目,通过paket引用Newtonsoft.Json。在这个项目中只有一个模块:

module Serializer =
  open System.IO
  open System.Text
  open Newtonsoft.Json

  type OptionConverter() =
    inherit JsonConverter()

    (* only the signature is important, the implementation
       and other methods are not interesting *)
    override x.WriteJson(writer: JsonWriter, value: obj, serializer: JsonSerializer) =
      (* ... *)

  let fromJson<'a> (bytes: byte []): 'a =
      let s = Encoding.UTF8.GetString(bytes)
      use sr = new StringReader(s)
      use jr = new JsonTextReader(sr)
      let serializer = JsonSerializer()
      serializer.Converters.Add(OptionConverter())
      serializer.Deserialize<'a>(jr)

现在让我们在同一个解决方案中创建第二个项目,并通过项目参考引用SerializerProject。我想在我的新项目中使用fromJson,这就是我首先引用SerializerProject的原因。

module MyModule =
  open Serializer

  (* This is here just so we reference the fromJson function *)
  let deserializer bytes = fromJson bytes

这是重现行为的最小例子。

现在,当我在Debug配置中构建解决方案时,一切都编译并正常工作。但是当我切换到Release时,编译在第二个项目中失败,在deserializer定义中的MyModule中。确切的错误信息是:

  

通过&#39; Newtonsoft.Json.JsonWriter&#39;引用的类型在未引用的程序集中定义。您必须添加对程序集的引用&#39; Newtonsoft.Json&#39;

我使用Visual Studio 2015 Update 3,F#工具(fsc,fsi)显示版本14.0.23413.0。

这是有道理的,因为它正在阅读SerializerProject的元数据,并发现公开OptionConverter类型在其公开JsonWriter上泄漏了WriteJson类型方法(以及其他类型和其他方法,但首先遇到这个方法),但是让我想知道为什么它在调试模式下有效并且只是Release模式中的问题。

  • 编译器会做什么样的额外操作会影响这个?
  • Newtonsoft.Json中定义的类型真正泄漏到第二个项目中时,为什么这不是Debug构建中的问题?

正如评论中所建议的那样,我尝试引用Newtonsoft.Json并使用ILSpy反编译第二个程序集,以查看编译器优化是否启用内联是否应该归咎于此,但即使在Release配置中,第二个程序集如下所示: / p>

call !!0 [SerializerProject]Serializer::fromJson<!a>(uint8[])

fromJson函数尚未内联直接显示JsonWriter类型,因此似乎有更微妙的内容。

这不是阻塞问题,我只是将转换器类型设为私有,因为我不想从外面使用它们,但我想深入挖掘F#编译器内部工作原理

0 个答案:

没有答案