Я получаю следующее сообщение об ошибке, когда пытаюсь загрузить (с помощью отражения) .dll, созданную с использованием служб компилятора F # (даже при том, что метод 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()
Я использую .NET Core в Ubuntu.
Однако, если я собираю с использованием кода Visual Studio, я могу загрузить сборку. Я открыл обе сборки и заметил, что у версии, которая не работает, есть переопределение для одного из методов 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 # Compiler Services:
// 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. Тем не менее, я не могу получить код для компиляции без этих явных ссылок.