.NET Core Version:
.NET Core 3.x -> .NET 5
Have you experienced this same bug with .NET Framework?:
No
Problem description:
The System.Windows.Forms.Design.Editors.dll assembly has been removed in .NET 5, which can cause applications built with .NET Core 3.x to fail if they used a type from that assembly and are permitted to roll forward on major versions.
Expected behavior:
The application should not fail. Instead, a System.WinForms.Forms.Design.Editors.dll should be included that contains type forwards for all of the types that were moved out of that assembly. In this way, WinForms on .NET 5 remains binary compatible.
Minimal repro:
System.Windows.Forms.Design.Editors.dll, e.g. AnchorEditor.<app name>.runtimeconfig.json with the following content (update the .NET5 SDK version as necessary):JSON
{
"runtimeOptions": {
"tfm": "netcoreapp3.0",
"rollForward": "LatestMajor",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "5.0.0-preview.2.20119.5"
}
}
}
System.Windows.Forms.Design.Editors.dll executes.[EDIT] updated the repro steps
@RussKie @merriemcgaw just FYI if you intend to preserve binary compatibility between 3.x and 5.0 you cannot add proper generic collection support (#2644). Return types of GetEnumerator have to change in order for foreach to pick it up; this will break applications which roll forward from 3.x (just tested). Since loops over collections are probably going to be pretty common you can't treat it as an exceptional case, it'll probably affect every nontrivial application rolling forward from 3.x
IMHO requiring a recompile for 5.0 is not entirely unreasonable and its probably one of the better chances to modernize winforms, it'll probably only get harder from there on.
So ultimately you'll have to make a strategic decision here what your goal for the 3.x/5.0 transition is, and the sooner its done and communicated the better.
Trying this repro and testing Igor's fix shortly.
@weltkante thank you, but you may be misinterpreting the intent of this work.
Whilst this bug is may affect our users, and it may not be totally unreasonable to ask to recompile, it is not the main driving factor here. The bug is currently blocking the VS Designer from rendering previews for different versions of .NET Core/.NET (due to a number of API moved from one assembly to another), and we don't expect to build a version of the Designer for each .NET version.
Other API proposals likely won't have a significant effect on the Designer, as those do not touch type editors and type converters.
@RussKie I'm just saying that if #2644 is implemented the work done here doesn't matter because roll-forward will fail anyways as soon as anyone has an foreach loop (which is pretty likely). Giving people the false impression that roll-forward will work in "some cases" may be counterproductive because ensuring that nobody has an foreach loop over a WinForms collection will be pretty much impossible (its enough if a single library has such a loop). Personally I'd prefer a clear error message that you need to recompile (or dropping #2644 if the impact is considered too large). In either way I wanted to make sure you are aware of the consequences the not yet merged PR would have.
we don't expect to build a version of the Designer for each .NET version. Other API proposals likely won't have a significant effect on the Designer, as those do not touch type editors and type converters.
You'll have to make sure not using foreach loops over WinForms collections in the designer then (probably can pass the collection through a helper method so the foreach doesn't see the specific class you are iterating over)
@weltkante: Why would roll forward break with #2644 for foreach loops? I would expect that IEnumerable implementation is _not_ being removed from types and binary compatibility would be preserved.
The interface doesn't matter, Roslyn doesn't look at the interface, it looks at the return type of public GetEnumerator methods so those need to change to return the generic IEnumerator<> otherwise foreach won't pick it up. If the return type of the method changes you get a MethodNotFound exception when you compiled against the old GetEnumerator which returned non-generic IEnumerator.
You can implement generic collections without changing the return type (for LINQ support) but then you won't get foreach (var control in container.Controls) type inference and also won't get proper nullability annotations, so you'll have to continuously work around nullability complaints when using WinForms.
@weltkante: I suppose that would result in a break if my application was previously compiled against the public GetEnumerator() method. For reason, I would argue very strongly against taking a change like that. Forward compatibility is extremely important. Introducing a break like this would break any third-party library compiled against netcoreapp3.1.
I'd be very interested in a proposal that improves productivity with the existing APIs without breaking the entire ecosystem to do.
Most helpful comment
@RussKie @merriemcgaw just FYI if you intend to preserve binary compatibility between 3.x and 5.0 you cannot add proper generic collection support (#2644). Return types of GetEnumerator have to change in order for
foreachto pick it up; this will break applications which roll forward from 3.x (just tested). Since loops over collections are probably going to be pretty common you can't treat it as an exceptional case, it'll probably affect every nontrivial application rolling forward from 3.xIMHO requiring a recompile for 5.0 is not entirely unreasonable and its probably one of the better chances to modernize winforms, it'll probably only get harder from there on.
So ultimately you'll have to make a strategic decision here what your goal for the 3.x/5.0 transition is, and the sooner its done and communicated the better.