Search code examples
c#build-process

Is C# compile/build an incremental process?


Our solution contains lots of C# projects. There are complicated dependency relationship between them, eg. project A/B/C, A dependents on B, B dependents on C. If I change one file in project C, then rebuild the solution, project A,B,C will be rebuild together.

In C++, build contains two process, compile and link. If I change one file in project C, then I build the solution, the relevant file in A and B will be compiled(other's files won't be compiled, their .obj will be reused in link process), then do link.

In java, just the changed file in project C will be recompiled, others file will be kept then package to .jar. It reuse previous work output(not changed file's .class).

In a word, C# doesn't reuse any previous work output. It doesn't have any middle file just like Java's .class and C++'s .obj. So in this point, I feel C# doesn't do incremental build process. Some little change will cause a big build process. I don't understand why C# doesn't use previous work output to accelerate the build process.

I am not sure whether my understanding of C# compile/build process is right. Could you please help to explain more? Thanks a lot.


Solution

  • The C# compiler does incremental compilations, I'm not sure where you got the idea that it doesn't. Maybe, due to the complexity of your solution, you are not understanding the dependencies correctly and projects that you assumed would not need to be recompiled are in fact necessary.

    The best way to check the compiler's behavior is to create a simple dummy solution and play around with it:

    Setup:

    1. Create an empty Visual Studio C# solution.
    2. Add any two projects, A and B.
    3. Make project B a reference in project A.
    4. Implement a class FooInB in B and use it in another class in A BarInA.

    Now lets play around a bit with this setup:

    1. Compile the solution. You will see that both projects compile.
    2. Compile the solution again. You will see that none of the projects compile, both are up to date.
    3. Change the implementation in BarInA and compile again. You will see that only one project compiles, A. There is no need to compile B again as there are no changes.
    4. Change the implementation in FooInB and compile one last time. You will see that both projects compile. This behaviour is correct, A depends on B so any change in B will necessarily need that A recompile again to make sure it is pointing to the latest version of B. In a theoretical world where the C# compiler could detect if the changes in B have no consequences in A and could therefore "optimize" away building A again, would be a nightmare scenario where each project could be referencing different and outdated assembly versions.

    That said, I'd like to point out that, AFAIK, the C# compiler will only perform incremental compilations at project level. I am not aware of any incremental compilation optimizations at class level inside any given assembly. Someone with much more insight in the inner workings of the compiler might be able to clarify this behavior.