当我尝试加载(通过反射)使用 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。但是,如果没有这些显式引用,我将无法编译代码。