Along with the beta versions of VS 2011 and Windows 8, many people will install and deal with .NET 4.5. In .NET 4.5, many new enhancements have been added that are fairly transparent, but it is important to understand how, from a CLR point of view, it works on your machine.
When .NET 4.5 is installed, it actually replaces .NET 4.0 on your machine. .NET 4.0 is overwritten by the new version of .NET 4.5, which, in accordance with the words of Microsoft, guarantees 100% compatibility. 100% compatibility sounds attractive, but we all know that to achieve this result is quite difficult. But there is a much more interesting thing than backward compatibility, which makes the situation with the deployment of .NET 4.5 uncomfortable at best and confusing at worst.
What does an update in place mean?
When you install .NET 4.5, your assemblies from .NET 4.0 in the \ Windows \ .NET Framework \ V4.0.30319 folder are overwritten by a new set. As a result, you are left with overwritten assemblies, as well as with a bunch of new ones (for example, the System.Net.Http assembly). The following image shows the System.dll build for .NET 4.5 (left) and for .NET 4.0 (right):

')
Obviously, these are different files with different sizes (interestingly, the .NET 4.5 version is smaller than the size).
That's not all. If during the execution of an application with .NET 4.5 installed, you refer to the Environment.Version property, then you still get 4.0.30319.
If you open the properties window of the System.dll assembly in .NET 4.5, you will also see

Please note that the file version is still 4.0.xxx.
The difference is in the build number: in .NET 4.0 it is equal to 261, while in the current beta version of .NET 4.5 it is equal to 17379. I think you can use the layout number to determine the version of .NET: if it is more than 17000, then This is .NET 4.5, however, this is not a very beautiful solution.
There is no simple or obvious way to determine which version of .NET 4.5 or .NET 4.0 is used, since they are the same for the application.
Compile for .NET 4.5 and run on .NET 4.0 is not a good idea.
You can compile an application under .NET 4.5 and run it under .NET 4.0 until you go beyond the functionality available only in .NET 4.0. At this point, the application will simply crash. Say, your code basically uses the features of .NET 4.0, but there are several places deeply hidden in the application that use the new features of .NET 4.5, for example, async / await. .NET will happily launch your application and execute successfully all the code until it encounters code that uses the capabilities of .NET 4.5, and then safely crashes. What joy!
Of course, you can run applications written for .NET 4.0 on .NET 4.5 and this should work without
any freaks .
Version detection
If you are writing an application for .NET 4.5, you have some control over its execution using the configuration file. You can specify that the application needs .NET 4.5, for example, like this:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework, Version=v4.5" /> </startup> </configuration>
This is done to ensure that the application does not launch an error on .NET 4.5, instead of crashing at runtime.
Also, web applications on .NET 4.5 can use the targetFramework property to achieve similar results.
<configuration> <system.web> <compilation debug="true" strict="false" explicit="true" targetFramework="4.5" /> </system.web> </configuration>
This works well for individual desktop and web applications, but there is no way for assemblies to be added to a project. For a project on .NET 4.0, the .NET 4.5 build looks like any other .NET 4.0 build.
For developers, especially developers of components, this is especially problematic, since there is no way to determine the version of .NET, because the Environment.Version property returns 4.
The following code displays
void Main() { Environment.Version.ToString().Dump(); Environment.Version.Build.Dump(); Environment.Version.Revision.Dump(); Environment.Version.Major.Dump(); }
on .NET 4.0
4.0.30319.269
30319
269four
on .NET 4.5
4.0.30319.17379
30319
17379four
Enough seems not? Note, however, that the revision number is more in .NET 4.5 - 17379, while in .NET 4.0 - 261. If you really want to know that you are using .NET 4.5 or .NET 4.0, you can use the following code:
public static bool IsDotNet45() { return Environment.Version.Major == 4 && Environment.Version.Revision > 17000; }
The second way is to try to detect some type added in .NET 4.5 using reflection.
public static bool IsNet45OrNewer() {
One of the advantages of this approach is that it can be used in later versions of .NET.
Nevertheless, it is rather indicative that we have to resort to such tricks to simply find out the compatibility of the versions.
Difference with .NET 3.0 / 3.5
Note that this in-place update is very different from the .NET 2.0 update to .NET 3.0 / 3.5 (it was also in place), which worked on the second version of the CLR. Both 3.x versions were just library enhancements over the .NET 2.0 kernel. Both versions were running .NET 2.0, which was not changed throughout the 3.x cycle. In turn, the update number 4.5 completely replaces .NET 4.0 leaving the actual version number of v4.0.30319.
When you create a new project in VS 2011, you can still choose a version of .NET 4.0 or .NET 4.5. But in fact, you refer to the same set of assemblies, regardless of the version you choose. The difference is that when compiling under .NET 4.0, the compiler provides only a subset of the features available in NET 4.0, but when compiling under .NET 4.5 you can use all the functionality. This does not mean that you can use VS 2010 to develop applications for .NET 4.5.
Good news is bad news.
Microsoft is trying to experiment in all possible ways to deploy new versions of .NET. There are no two updates that are the same. Of course, a full update (such as .NET 2.0, 4.0) has its drawbacks, but it is not entirely correct to make an update on the spot and even provide a way to determine the current version of .NET, even according to Microsoft standards. Especially considering that .NET 4.5 is a fairly large update with all async-s. Most APIs that use IO have been updated to support async-s, which significantly affected the existing API. Worse, .NET 4.5 will ship with Windows 8, so it will be with us for a long time, unless of course Microsoft finally decides to upgrade the .NET version as part of the system upgrade. It was the same with Vista, which came with an intermediate version of .NET 3.0, which was quickly replaced with a more practical and long-lived .NET 3.5. People had enough problems with the confusing situation with 3.x versions, which actually worked on .NET 2.0. I can't even count the number of questions asked that people can't find .NET 3.5 in the IIS dialog box. The same can happen with .NET 4.5. Well, when we know the way to upgrade to version 4.5, but administrators who are not completely familiar with .NET are unlikely to understand these nuances, and ultimately what version of .NET will be confused.
It is difficult for me to see an advantage in this way of updating, I did not even see a clear explanation of why this approach was chosen. Of course, with this approach, existing bindings to assemblies do not break, so the application can remain working after the update. I think this may be useful for some component suppliers. But seriously, are you really going to mix .NET 4.0 and .NET 4.5 (without recompiling the application), and then test everything thoroughly to make sure everything works? Recompilation does not seem to be serious in the light of a transparent version update.