By “Frameworks assemblies,” I mean the assemblies that ship with the CLR. But, I’m not counting mscorlib.dll, since it’s special in a different way.
With v1.0 SP3 or later, Frameworks assemblies are unified. That means that the version of those assemblies that you request is ignored – you get the version that matches the loaded CLR. This only applies when the assembly is loaded by version – that is, by assembly display name or static reference (AssemblyRef in the CLR metadata).
For example, if the v1.1 CLR is loaded and you request v1.0’s system.dll, then you’ll get the v1.1 system.dll back. If you load it by path from c:\foo\system.dll, however, then you’ll get c:\foo\system.dll back, not the v1.1 system.dll.
Those assemblies are unified because the owners of the code feel that they are so closely tied to the CLR/mscorlib.dll that they should not be loaded with a different version than they were built against. Additionally, there are some cases where they expect that only one copy of the Frameworks assemblies be loaded in a given process.
If the v1.0 (pre-SP3) CLR is loaded, though, you will get the assembly that you ask for. Unification isn’t done for Frameworks assemblies in that version.
Do not rely on this behavior. You should still fully-specify assembly references with the correct version. That’s just good practice, in general. Besides, if your assembly is loaded in a CLR later than v2.0, those references may not be unified, so you may get unexpected behavior.