kind of farewell to .Net Framework

JohnH

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
1,721
Location
Norway
Programming Experience
10+
Finally took the time to upgrade all my projects to .Net 8. A few were .Net 6/7 and easy, but most from .Net Framework 4.8. Upgraded around 50 projects in a week.
I didn't like the upgrade assistant when I tested that before so I just started new projects and copied in classes, and made necessary changes.

For winforms projects (yes, they're nice and easy to use for my quick "tools" with consistent GUI controls) I found that I could just copy the three files (code, designer, resx) in and they mostly were good to go.

Issues were Settings and Resources mostly, espescially settings with control bindings in designer file. The settings file I added in project properties first, copied in the old and "Run Custom Tool" on it, then moved any control bindings to user code.

There were some issues with xsd files and typed datasets, I had to add and run custom tool MSDataSetGenerator to get rid of a warning about a constructor supporting out-of-support BinaryFormatter. I don't actually use databases and just had used xsd for convenience databinding a few places, so this was not a case of "should move to EF or something like that".

Couldn't get the new resource designer to work in current VS 2022 (17.11.5), so I just set the resource files as Embedded Resources and used Assembly.GetManifestResourceStream to load them, I didn't have many cases though.
ImageLists containing some images in a form were also trouble with BinaryFormatter serialization from resx, same here I moved the code to user file and loaded the images from Embedded Resources.

I got quite a few new code improvement suggestions, a lot of the projects were very old, some more than 10 years old and just up'ed Framework versions before. Minor improvements, but I did them all.
  • Apparently I have "always" used Count extension rather than Length property, "Count" reads better than "Length", but oh well, I fixed 300 occurrences anyway.
  • Dictionary.TryGetValue has escaped me, now I have learned I should not "guard" with ContainsKey and later lookup.
  • In VB projects vbNewline is deprecated, use vbCrLf (also less readble IMO) - or Environment.NewLine.
  • Lots of ToLower and Contains/Equals got the StringComparison upgrade for case insensitivity, often for checking file extensions.
  • Many "does not access instance data and should be marked static"
  • Many "use char literal for a single character lookup" (instead of single char string)
  • Many "mark readonly fields"
  • A few "don't use Count when Any can be used"
  • Use Array.Empty instead of empty array (zero length array allocations)
  • and so on...
Noticed in forms projects the before default MS Sans Serif 8.25pt font is now Segoe UI 9pt. Expands everything a bit.

Lots of Nuget packages were updated, several versions in some cases, but very few required code changes.

Got to discard a few projects that were just lying around and no longer had any use, made some quick code cleanups along the way, and merged a couple of projects too.

I all, it took less time than I thought, with less troubles, all worth the spare time hours last week. Now I can kind of relax for a couple of years, and easier move on from .Net 8 later. (.Net 9 is up in November already I see 😯)

Still have a couple of Office VSTOs and a VB windows service in .Net Framework, other than that it is .Net only here now. 🤘
 
Be glad that you don't have any encrypted web.config files to deal with.
 
Now on to tracking all uses of Encoding.Default where files are not UTF8.
 
Changed Newtonsoft.Json to System.Text.Json in a project, and got a bug deserializing a readonly collection property. NJ deserialized it, while STJ didn't. Luckily found option JsonObjectCreationHandling.Populate took care of it.

Also found a few Process.Starts that needed UseShellExecute which changed default from .Net Framework to .Net.

Probably not the last bugs that will arrive later.
 
I thought there was also an ordering issue with regards to the System.Text.Json, but I can't recall the details.
 
I think json order should not matter, just like xml siblings, but I do have one project where deserializing one property depends on another, I used STJ JsonPropertyOrder attribute which worked as advertised.
 
Yeah, it shouldn't matter, but apparently that is what caused a breaking change in the latest PowerShell and AzureFunctions.
 
and they mostly were good to go

Winforms apps are the one thing I'll probably carry on doing in FW, just because I like datasets and app settings bindings and a few other things that MS broke in core and (afaik) still haven't/wont fix

There is still definitely a place for WF in my life, but I think most of what I would have used WF before I'd now look to do as a Blazor server side app with EF..
 
Last edited:
  • Apparently I have "always" used Count extension rather than Length property, "Count" reads better than "Length", but oh well, I fixed 300 occurrences anyway.
I'm sure if we look in source code we'll find there is a type specific handling that causes Count() to return the length of an array anyway; I highly doubt that in 2024 using Count() on an array does a "foreach(var _ in array) i++; return i;" so we're down to arguing about the overhead of calling a method

  • Dictionary.TryGetValue has escaped me, now I have learned I should not "guard" with ContainsKey and later lookup.
Yes, though I don't like it as much for readability as GetValueOrDefault (I haven't checked recently but I think classically this ext method used ContainsKey)
  • A few "don't use Count when Any can be used"
That one's the other way round for me; roslynator (I think) tells me off for Anying when Count is available.

  • Use Array.Empty instead of empty array (zero length array allocations)
That's now given way to collection expressions for me, I think

  • and so on...
Do you use any CA extensions? I've a few, the roslynator already mentioned, async fixer and async method name fixer, and sometimes meziantou (a per project analyzer installed as a nuget package)
 
That one's the other way round for me; roslynator (I think) tells me off for Anying when Count is available.

I noticed those too, they both refer back to each other in notes, it's about Count extension vs property.
CA1827: Do not use Count/LongCount when Any can be used (code analysis) - .NET | Microsoft Learn
CA1860: Avoid using 'Enumerable.Any()' extension method - .NET | Microsoft Learn

Do you use any CA extensions?

There's a few analyzers in each project, but I haven't added any manually. Stock VS install in that regard.
 
Back
Top Bottom