为同时使用C#和F的项目求解循环引用#

为同时使用C#和F的项目求解循环引用#,c#,f#,circular-dependency,C#,F#,Circular Dependency,这就是我的情况。我在C#有一个类库。它公开了一些类型,如矩形。它还公开了一些进行算法计算的方法 用F#写这些算法位似乎是个好主意。因此,我在解决方案中添加了另一个F#library项目 现在问题来了。为了让F#项目进行算法计算,它需要了解C#项目中的矩形。为了让C#项目能够使用F#函数,它需要引用F#项目。这就是循环引用 一个可能的解决方案是使用第三个项目,我可以在其中定义矩形,然后从F#和C#引用该项目,然后从C#引用F#项目,这样我就可以使用这些函数 这样做的问题是,我的库的用户不仅要引用我

这就是我的情况。我在C#有一个类库。它公开了一些类型,如
矩形
。它还公开了一些进行算法计算的方法

用F#写这些算法位似乎是个好主意。因此,我在解决方案中添加了另一个F#library项目

现在问题来了。为了让F#项目进行算法计算,它需要了解C#项目中的
矩形。为了让C#项目能够使用F#函数,它需要引用F#项目。这就是循环引用

一个可能的解决方案是使用第三个项目,我可以在其中定义
矩形
,然后从F#和C#引用该项目,然后从C#引用F#项目,这样我就可以使用这些函数

这样做的问题是,我的库的用户不仅要引用我的C#项目,还要引用额外的第三个项目(因为使用需要向算法提供输入)

这是不可接受的,因为使用F#只是一个实现细节,我不希望它在我的库的使用方式上有任何开销

那么让我们假设
矩形
保留在C#项目中。算法的F#实现(C#中调用F#中函数的方法)的“接口”也在C#项目中。我如何将它们连接起来以使其工作?还有其他选择吗

对我来说,拒绝循环引用似乎很奇怪。像这样紧密绑定的项目并没有真正的有向图结构


我知道还有一个额外的方法。F#项目拥有自己的
矩形
,然后在两端进行序列化和反序列化。这既单调乏味,又与使用F#简化代码的最初想法相反。

听起来您真正的问题不是依赖性本身,而是对“打包”的关注(必须运送三个程序集,并且最终用户需要链接到多个程序集),您可以考虑将程序集组合到单个DLL中。这使您可以在项目中使用适当的解耦,同时仍然可以方便地为库提供单个文件。这是第三方库供应商非常常用的策略


也有各种商业工具可以执行此过程并执行其他操作,如模糊处理、许可证强制执行等。但尚不清楚这是否真的对您的应用程序是必要的。

您这里真正的问题并不是真正的C/F问题(尽管这会触发它),但是一个程序集
A
不能从另一个程序集
B
重新导出类型,而不要求
A
的用户也引用
B


我建议通过在F#assembly中定义
Rectangle
来解决这个问题,但在C#assembly中定义一个新的
Rectangle
作为包装器类型,将F#
Rectangle
作为私有成员。然后,您还可以使用包装函数公开底层的F#算法,并提供一个构造函数来调用代码以直接使用。

在C#rectangle类实现的F#项目中创建一个矩形接口怎么样?这是否仍然意味着对C#rectangle的引用需要对F#assembly的引用?是的,但是现在F#one不需要C#。它只是公开与接口一起工作的函数。实际上,这似乎不起作用。。。我仍然需要在使用
Rectangle
类的任何地方引用F#assembly,因为它实现了来自该程序集的接口。肯定有这样的解决方法。是的,我想如果唯一需要考虑的是库用户还必须记住引用FSharp.Core,那么在F#library中编写所有与计算相关的内容,然后将程序集合并在一起是最简单的…@Patryk,ILMerge实际上支持自动“内部化”引用,这意味着您可以在最终打包的程序集中对F#“helper”程序集隐藏公共类,同时仍将它们实现为“public”,以便在原始设计中使用。通过这种方式,您实际上不应该要求任何对FSharp.Core的引用。这当然是一种选择,但我认为Matthew在评论中的建议可能是最佳选择。我会看看我是否会遇到更多的麻烦。我会把这个答案标记为正确答案,因为它回答了我的实际问题,即使有更好的方法来处理我的情况,不会导致这个问题。