在.NET BCL中,有以下几个循环引用:
System.dll
和System.Xml.dll
System.dll
和System.Configuration.dll
System.Xml.dll
和System.Configuration.dll
这是.NET Reflector的截图,显示了我的意思:
微软如何创建这些程序集对我来说是一个谜。是否需要特殊的编译过程才允许这样做?我想这里有一些有趣的东西。
答案 0 :(得分:56)
我只能告诉Mono Project如何做到这一点。这个定理很简单,虽然它给代码搞乱了。
他们首先编译System.Configuration.dll,而不需要引用System.Xml.dll的部分。在此之后,他们以正常方式编译System.Xml.dll。现在来了魔术。他们重新编译System.configuration.dll,该部分需要引用System.Xml.dll。现在有一个圆形引用的成功编译。
简而言之:
答案 1 :(得分:35)
RBarryYoung和Dykam正在努力。 Microsoft使用内部工具使用ILDASM来反汇编程序集,删除所有内部/私有内容和方法主体,并再次将IL重新编译(使用ILASM)到所谓的“脱水程序集”或元数据程序集中。每次更改装配的公共接口时都会这样做。
在构建期间,使用元数据程序集而不是实际的元数据程序集。这样循环就被打破了。
答案 2 :(得分:26)
它可以按照Dykam描述的方式完成,但Visual Studio会阻止你这样做。
您必须直接使用命令行编译器csc.exe。
csc / target:library ClassA.cs
csc / target:library ClassB.cs /reference:ClassA.dll
csc / target:library ClassA.cs ClassC.cs /reference:ClassB.dll
//ClassA.cs
namespace CircularA {
public class ClassA {
}
}
//ClassB.cs
using CircularA;
namespace CircularB {
public class ClassB : ClassA {
}
}
//ClassC.cs
namespace CircularA {
class ClassC : ClassB {
}
}
答案 3 :(得分:17)
只要你不使用项目引用,它在Visual Studio中就很容易了...试试这个:
所以你就是这样做的。但是说真的......难道你不是在真正的项目中做到这一点!如果你这样做,圣诞老人今年不会带给你任何礼物。
答案 4 :(得分:6)
我想可以通过从一组非循环程序集开始并使用ILMerge将较小的程序集合并到逻辑相关的组中来完成。
答案 5 :(得分:4)
好吧,我从来没有在Windows上完成它,但我已经在很多编译链接-rtl环境中完成了它,它们是它的实际祖先。你要做的是首先制作存根“目标”而不用交叉引用然后链接,然后添加循环引用,然后重新链接。链接器通常不关心循环引用或跟随引用链,它们只关心能够自己解析每个引用。
因此,如果您有两个需要互相引用的库A和B,请尝试以下方法:
Dykam提出了一个很好的观点,它是编译,而不是链接.Net,但原则保持不变:使用导出的入口点制作交叉引用的源,但除了其中一个源外,其他所有源都有自己的引用其他人潦倒。像那样构建它们。然后,取消存储外部引用并重建它们。即使没有任何特殊工具,这应该可以工作,事实上,这种方法已经适用于我曾经尝试过的每个操作系统(大约6个)。虽然显然可以自动化的东西会有很大的帮助。
答案 6 :(得分:1)
一种可能的方法是使用条件编译(#if)首先编译一个不依赖于其他程序集的System.dll,然后编译其他程序集,最后重新编译System.dll以包含依赖的部分在Xml和配置上。
答案 7 :(得分:0)
从技术上讲,它们可能根本没有编译,而是手工组装。毕竟,这些是低级库。