我们有一个F#程序集(AssemblyOne),该程序集在单个Visual Studio 2012解决方案中引用了另一个F#程序集(AssemblyTwo)。 AssemblyTwo引用了C#DLL(MyCSharpLib)。
AssemblyOne中定义的函数调用AssemblyTwo中定义的函数:

namespace AssemblyOne

[<RequireQualifiedAccess>]
module MyModuleA =
    let FetchResult id =
        let result = AssemblyTwo.MyModuleC.FetchResult id
        result

AssemblyTwo中调用的函数在同一程序集中调用另一个函数(FetchActualResult()),该函数采用属于所引用的C#DLL(MyCSharpType)的MyCSharpLib类型的参数:
namespace AssemblyTwo

[<RequireQualifiedAccess>]
module MyModuleB  =
    let FetchActualResult(myCSharpType:MyCSharpLib.MyCSharpType, id:int)
        //return a result

[<RequireQualifiedAccess>]
module MyModuleC =
    let FetchResult id =
        let myCSharpType = new MyCSharpLib.MyCSharpType()
        MyModuleB.FetchActualResult(myCSharpType, id)

该解决方案可以在Visual Studio中编译和构建。但是,当我们尝试使用MSBuild从命令行构建项目时,构建会失败,并在msbuild.log中出现以下错误:
error FS0074: The type referenced through 'MyCSharpLib' is defined in an assembly that is not referenced. You must add a reference to assembly 'MyCSharpLib'.

似乎在MyCSharpLibFetchActualResult()函数签名中作为参数从AssemblyTwo公开的类型导致了该错误。AssemblyOne现在需要引用MyCSharpLib,即使AssemblyOne不直接使用MyCSharpLib中的任何内容。
如果我们从函数签名中删除参数,则解决方案将正确构建。

通过使用以下用例(“->”表示程序集引用)复制代码,我们进一步探讨了此问题:
  • F#AssemblyOne-> F#AssemblyTwo-> MyCSharpLib(C#DLL)(不生成)
  • F#AssemblyOne-> F#AssemblyTwo-> MyFSharpLib(F#DLL)(不生成)
  • F#AssemblyOne-> F#AssemblyTwo-> C#AssemblyThree(在同一解决方案中组装)(不生成)
  • F#AssemblyOne-> F#AssemblyTwo-> F#AssemblyThree(在同一解决方案中进行组装)(内部版本)

  • 可以解释这种行为吗?

    最佳答案

    假设DWright指出您的源中有错别字,我想说这个错误可能是由于您使用此代码定义了带有外部类型MyCsharpType的公开方法参数的静态类MyModuleB所致。

    这是Fsharp代码转换为IL的方式(从ILSpy-重新转换为Csharp):

    ...
    public static class MyModuleB
    {
        public static string FetchActualResult(MyCSharpType myCSharpType, int id)
        {
            return myCSharpType.Fetch(id);
        }
    }
    

    如果不公开该类型以使其静态可见,则可能不会出现该错误。但是,这将取决于编译器的实现。

    我可以想象,在MyModuleA的编译过程中,编译过程或编译器版本的一种配置可以尝试“接触” MyModuleB,从而尝试达到未引用的参数类型,而其他配置可能不接触MyModuleB。这取决于。

    因此,在我看来,问题似乎不在编译过程中,而是实际上,您公开了一种类型的用法,而该类型并未引用其汇编。

    08-28 21:38