3

当我尝试加载(通过反射)使用 F# 编译器服务构建的 .dll 时,我不断收到以下错误消息(即使被抱怨的 Equals 方法确实存在于构建中):

Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Method 'Equals' in type 'XXX' from assembly 'YYY', Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeModule.GetTypes()
   at System.Reflection.Assembly.GetTypes()

我在 Ubuntu 上使用 .NET Core。

但是,如果我使用 Visual Studio Code 构建,我可以加载程序集。我打开了两个版本,我注意到不起作用的版本覆盖了 Equals 方法之一,而有效的版本没有。我不确定这是否有后果:

    [CompilerGenerated]
    public sealed bool Equals(object obj, IEqualityComparer comp)

对比

    [CompilerGenerated]
    public sealed override bool Equals(object obj, IEqualityComparer comp)

此外,当我使用 dnSpy 检查引用时,有效的版本引用了 .netstandard,而没有引用的版本没有此引用。我尝试在编译过程中添加对 .netstandard .dll 的引用,但这似乎没有任何效果。

我正在尝试构建的代码是一个简单的记录,大致相当于以下内容:

namespace Xxx

open System

type Yyy =
    {
        ServiceCategory : string
        DateRange : DateTime
    }

这是我使用 F# 编译器服务构建的代码:

 // Detect the file location for the library that defines the object type
      let corelibRefLocation = typeof<Object>.GetTypeInfo().Assembly.Location
      let corelibRefDirectory = Path.GetDirectoryName(corelibRefLocation)
      let mscorlibRefLocation = sprintf @"%s/mscorlib.dll" corelibRefDirectory
      let systemRuntimeRefLocation = sprintf @"%s/System.Runtime.dll" corelibRefDirectory
      let netStandardRefLocation = sprintf @"%s/netstandard.dll" corelibRefDirectory

      let staticArgs =
            [|
             "fsc.exe"
             "--noframework"            
             "-o"; outputPath;
             "-a"; sourcePath           
            |]

      let references =
           [|
             "-r"; corelibRefLocation
             "-r"; systemRuntimeRefLocation
             "-r"; mscorlibRefLocation 
             "-r"; netStandardRefLocation 
           |]

      let args = Array.concat([|staticArgs; references|])         

      let errors, exitCode = 
          checker.Compile(args)
           |> Async.RunSynchronously 

      match (errors, exitCode) with
      | [||], 0 -> Console.WriteLine("OK!")
      | _ -> Console.WriteLine("Not OK!")

我不确定为什么 .dll 没有加载以及我需要做些什么不同的事情。

更新:我已从 .net Core 2.1 升级。到 .NET Core 3.0,即使生成的代码现在不再包含覆盖,问题仍然存在。我现在可以观察到的有效版本(使用 VSCode 编译)和无效版本(使用 FCS 编译)之间的唯一显着区别是 FCS 版本明确引用了 mscorlib 和 System.Private.CoreLib。但是,如果没有这些显式引用,我将无法编译代码。

4

0 回答 0