我们有一个 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()
),该函数采用属于的 MyCSharpType
类型的参数到引用的 C# DLL (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'.
似乎是 AssemblyTwo
中 FetchActualResult()
函数签名中的 MyCSharpLib
公开的类型导致了错误。
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 指出的拼写错误,我想说这个错误可能只是因为您通过此代码定义了一个静态类 MyModuleB,其中公开了外部类型 MyCsharpType 的方法参数。
这是 Fsharp 代码转换为 IL 的方式(从 ILSpy - 重新转换为 Csharp):
...
public static class MyModuleB
{
public static string FetchActualResult(MyCSharpType myCSharpType, int id)
{
return myCSharpType.Fetch(id);
}
}
如果您不公开类型以使其静态可见,则可能不会出现错误。然而,这将取决于编译器的实现。
我可以想象,在 MyModuleA 的编译过程中,编译过程或编译器版本的一种配置可以尝试“触及”MyModuleB,从而尝试达到未引用的参数类型,而其他可能只是不触及 MyModuleB。这取决于。
所以在我看来问题不在编译过程中,但事实上,你公开了一个你没有引用其程序集的类型的用法。
关于c# - F# 程序集引用导致构建问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35128630/