.NET’s rigorous enforcement of version compatibility raises an interesting problem: if an application is built against version 2.0 of .NET, when version 3.0 of .NET becomes available, the application will not be able to take advantage of it. The reason is that the application’s manifest contains the version numbers of all the assemblies it relies on, including the CLR and application frameworks. The .NET assemblies are strongly named, and therefore the assembly resolver will insist on a perfect version match.
To overcome the issue of version compatibility with its own assemblies, .NET provides a different set of ground rules. The issues involved are intricate. The exact version of the CLR used by the components in a class library or an EXE may vary, and it depends on what they were compiled with, the available .NET versions, and the application versioning policy.
The .NET architects tried to strike a balance between allowing innovation and new versions on the one hand, and supporting existing applications on the other. Ultimately, it’s up to the application vendor to decide whether to support a particular CLR version. This marks a change of philosophy: Microsoft no longer guarantees absolute backward and forward compatibility. Instead, Microsoft pledges to make every effort to be backward-compatible and to point out where there are incompatibilities. That, of course, does not mean that a new .NET version will be fully backward-compatible; all it means is that in the ...