C# – How to make an application compatible with .NET 4.0 and .NET 4.5


I'm pretty new to .NET and C#.

I recently took up the task of upgrading my application from .NET 4.0 to .NET 4.5 to keep up with other products in my team.

I would like to be able to run my application (which has several projects, some web projects based on ASP .NET and some standalone app projects (console application)) on .NET 4 and .NET 4.5.

After following instructions online regarding <supportedRuntime> Element to upgrade from .NET 4.0 to .NET 4.5 by changing the target run-time I realized that the compilation element's targetFramework attribute is now 4.5. I understand that this means the code will definitely work on .NET framework 4.5.

What if I have a set of nodes that are waiting for 4.5 upgrade which are still running .NET 4.0. I'm pretty sure that my changes would break the application.

So I did some research and after referring to some documentation online, I've removed the sku attribute from the supportedRuntime element in the *.config files of the projects in the solution. Though the version attribute of the supportedRuntime element is still v4.0 (CLR version). I hope this make the application run on both .NET framework 4.0 and 4.5.

But I don't really know much about the compilation element and its significance apart from what I read from ASP .NET configuration guidelines. Would leaving the targetFramework make sure that my applications work on both .NET 4.0 and .NET 4.5?

How can I make sure that my changes are compatible with both .NET 4.0 and .NET 4.5?

[Why not leave it as .NET 4.0 till the nodes have their .NET frameworks upgraded?]

You might wonder why I can't keep it as .NET 4.0 for now.
The aim is to upgrade to .NET 4.5. But the standalone script runs on a set of nodes that run on Windows Server 2003 that does not support .NET 4.5. I've got my system admin team to allocate another node with .NET 4.5 for this process alone. So for the time being I can't really completely upgrade my existing code. Until after I test my existing code on .NET 4.5 and configure deployment to those new nodes.
Thanks to that comment from @hvd which lit a bulb in my confused brain. Now I know how to proceed.

Best Solution

The versioning of the .NET Framework is distinct from the versioning of the runtime (CLR and jitter). Already the case in previous versions, .NET 2.0, 3.0, 3.5 and 3.5SP1 used runtime version v2.0.50727.

Much the same for the 4.0 branch, versions 4.0, 4.0.1, 4.0.2, 4.0.3, 4.5, 4.5.1 and 4.5.2 all use the same runtime version, v4.0.30319

The "sku" attribute was added to provide the CLR with an extra check to ensure that the correct framework version is present on the machine. And powers this feature, very desirable. Without it, your 4.5 targeted project will start just fine on a machine that only has 4.0 installed. But will tend to fall over on a pretty ugly runtime exception, usually caused by a missing type or method. Especially the changes in 4.5 were rather impactful, types were moved from one assembly to another to make the footprint of the framework smaller on portable devices. This question is a good example, very ugly to diagnose.

A good example of how this went wrong before is the EventWaitHandle.WaitOne(int) overload. Added in .NET 2.0SP2 (aka 3.5). A good idea, nobody knew how to use the WaitOne(int, bool) overload properly. But a breaking change without a corresponding change in the [AssemblyVersion] for mscorlib. Causing horrible problems, programmers used the overload with gusto but their programs failed when it ran on an older version of .NET. Kaboom with a MissingMethodException, leaving very little clue how a simple and common method could be missing.

Cold hard fact is that if you target 4.5 in your project and remove sku then you'll get to deal with this kind of misery. You have to target 4.0 to keep compatibility, very simple to do of course.