Every assembly has an identity, which includes name, version, culture, and public key/token. Also every binary in Windows can have a file version. The file version is orthogonal to assembly version, and there is no co-relation at all. You can change them independently. And file version is not used in binding decision at all. For .Net assembly, it is pure informational.
Unless the assembly is about to be installed to GAC.
In .Net framework 1.1 we introduce the file version when you install assemblies into GAC. It only applies when the assembly you are about to install already exist in GAC. When we see the assembly already exists in GAC, we try to compare the file version of the assembly in GAC(let’s call it “old” assembly), and the file version of the assembly about to install(and “new“ assembly). If the “new” assembly’s file version is lower than the “old” assembly’s, we will refuse to install the “new” assembly, unless you ask fusion to force install (“gacutil -if“).
The intention is that replacing assembly with old bits is almost a mistake 99% of the time. You really have to “force” us to do the “wrong” thing.