A long path away from the .NET Framework. Part 3 – Differences

  •   Posted in:
  • .NET

The previous part is here.

And finally, we are in the most important part which explains what works differently between the .NET Framework and .NET 6. Just in case I will talk about behavioral changes and about obvious parts like some methods that do not exist in .NET 6 but I will

  1. The .NET Framework will suppress all exceptions when it releases a reference to a COM object but .NET 6 will crash. One example of such a problem is when some object is freed despite having a reference count of more than zero. It is a bug and needs to be fixed. I just was surprised by how often it happened in our application.
  2. Accessing .NET from DllMain will lead to deadlocks. We had these in the .NET Framework, but they happened much more often in the .NET 6. And obviously, it needs to be fixed. It will take some time because it works most of the time and deadlock happens quite seldom.
  3. string.GetHashCode will return different values every time you start the application. Basically during startup runtime will generate a random seed and add it to the hash code. If you want hash code to persist then write a function that hashes string differently.
  4. When the application converts a floating point number to a string, the result will be slightly different. Here blog post that explains the changes. For example, when the .NET Framework outputs 3.1415, .NET may output as 3.141500001 or 3.141499999.
  5. Encoding.Default will be always UTF8 in .NET 6. If you want to return old behavior then you need to create Encoding from the current Windows code page.
  6. System.Diagnostics.ProcessStartInfo.UseShellExecute is true for .NET Framework but false for .NET As a result, previously it was possible to open the http link without changing properties but now UseShellExecute must be set specifically to true.
  7. Previously it was possible to bind to read-only property in WPF. Now it throws an exception and you need to add “, Mode=OneWay”.
  8. SHA512.Create("System.Security.Cryptography.SHA512CryptoServiceProvider") will return null. We replaced it with new SHA512CryptoServiceProvider().
  9. There is no SHA512Cng class. We replaced it with SHA512CryptoServiceProvider class that uses SHA512Cng internally when the application is running for Windows.
  10. Setting SecurityProtocolType.Ssl3 will throw an exception.
  11. Some controls were removed from WinForms. For example ContextMenu. They were replaced with a set of different controls quite some time ago but our code used an old version for some reason.
  12. In the .NET Framework, your application can load assembly A from the application directory. Later it can load assembly K located in a different directory and assembly K can load assembly A version from the same directory that contains assembly K and it will work. This will fail in the .NET 6 because another version with a higher version is already loaded. To fix this you will need to use AssemblyLoadContext.
  13. If you are using different assembly versions in WPF then it will work properly. You will have to rename assemblies to include the version in the assembly name. I spent quite a bit of time on this and I didn’t find any better way.
  14. If you are enumerating over HashSet sometimes it will contain elements in a different order in .NET 6. We found that during tests. But HashSet does not guarantee the order so it was an issue on our side.
  15. string.Compare("C-O", "CA") will return 1 for the .NET Framework and -1 for .NET 6. It is because Microsoft changed how comparing works to have the same result for all platforms. Previously it used Windows API for this.

I hope it helps someone.


Post comment