我们的解决方案包含许多C#项目.它们之间存在复杂的依赖关系,例如.项目A/B/C,B上的家属,B上的家属.如果我在项目C中更改一个文件,然后重建解决方案,项目A,B,C将一起重建.
在C++中,build包含两个进程,编译和链接.如果我在项目C中更改了一个文件,那么我构建解决方案,将编译A和B中的相关文件(其他文件将不会被编译,其.obj将在链接过程中重用),然后进行链接.
在java中,只需重新编译项目C中的已更改文件,其他文件将保留,然后打包到.jar.它重用以前的工作输出(未更改文件的.class).
总之,C#不会重用任何以前的工作输出.它没有任何中间文件,就像Java的.class和C++的.obj一样.所以在这一点上,我觉得C#不做增量构建过程.一些小的改变将导致一个大的构建过程.我不明白为什么C#不使用以前的工作输出来加速构建过程.
我不确定我对C#编译/构建过程的理解是否正确.你能帮忙解释一下吗?非常感谢.
在C#编译器编译增量,我不知道你在哪里得到它不想法.也许,由于您的解决方案的复杂性,您无法正确理解依赖关系,并且您认为不需要重新编译的项目实际上是必要的.
检查编译器行为的最佳方法是创建一个简单的虚拟解决方案并使用它:
建立:
创建一个空的Visual Studio C#解决方案.
添加任何两个项目,A
和B
.
使项目B
成为项目中的参考A
.
实现一个类FooInB
,B
并在另一个类中使用它A
BarInA
.
现在让我们玩这个设置吧:
编译解决方案.您将看到两个项目都编译.
再次编译解决方案.您将看到没有任何项目编译,两者都是最新的.
更改实现BarInA
并再次编译.你会看到只有一个项目编译,A
.B
由于没有变化,因此无需再次编译.
更改实现FooInB
并最后一次编译.您将看到两个项目都编译.这种行为是正确的,A
取决于B
所以任何更改B
都必须A
再次重新编译以确保它指向最新版本B
.在理论世界中,C#编译器可以检测到更改B
是否没有后果A
并因此可以"优化" A
再次构建,这将是一个噩梦场景,其中每个项目可能引用不同的和过时的汇编版本.
也就是说,我想指出,AFAIK,C#编译器只会在项目级别执行增量编译.我不知道任何给定程序集内的类级别的任何增量编译优化.对编译器内部工作有更多洞察力的人可能能够澄清这种行为.