Overloads with string parameters should be included in .NET 6.0 build to maintain binary backwards compatibility with .NET Standard 2.0
NoahStolk opened this issue · comments
From this comment: #412 (comment)
Since overloads for ReadOnlySpan<char>
have been added, methods using string
are no longer included in the .NET 6.0 build, which causes runtime errors in binaries where both versions are used through different projects.
How to reproduce:
- Create 2 projects; one .NET Standard 2.0 and one .NET 6 or 7. Reference ImGui.NET in both projects, either through
ProjectReference
orPackageReference
. - Call an
ImGui
method with astring
parameter from the .NET Standard 2.0 library. - Call the library from the other project. It will crash because the .NET Standard 2.1 version of ImGui.NET has been compiled and included in the binary, while the .NET Standard 2.0 library expects the methods present in the .NET Standard 2.0 version.
To fix this we'd need to include string
overloads again. However, this results in the string
overloads taking precedence over ReadOnlySpan<char>
which means you'd have to write ImGui.Text("Hello, world!".AsSpan());
instead of ImGui.Text("Hello, world!");
(I think).
Related issue: zaafar/ClickableTransparentOverlay#48
Is there any reason why someone would use both 2.0 and 6.0 at the same time in different projects?
I feel like there could be many reasons. I guess it could make sense to build a .NET Standard 2.0 library with common or shared ImGui rendering logic that can then be re-used in any other project regardless of whether it is using .NET Standard 2.0, .NET 7, or .NET Framework.
I realize now from the other thread that if you multi-target a library, you need to be binary backwards compatible (meaning the method signatures need to match) with each "lower" target. So in this case, everything that is available for .NET Standard 2.0 should also be available for .NET 6.0. (Obviously not the other way around, since you can't target a .NET 6 project from a .NET Standard 2.0 one.)
I think I've found a workaround for anyone not able to upgrade to .NET 6 running into this issue:
Remove ImGui.NET from the other project that is on .NET 6 or 7. This makes sure ImGui.NET will be coming as a transitive dependency from the other .NET Standard 2.0 project. I'm fairly sure the .NET Standard 2.0 build of ImGui.NET would then be resolved and there would not be any method signature mismatches.
We are getting widespread reports from Silk.NET users that this change has broken our downstream consumers.
Consider this:
- Helper library targets .NET Standard 2.0, expecting the string variant to be there
- When the helper library is published, it compiles successfully with a metadata reference to the string version.
- Because NuGet is smart, it automatically picks the most appropriate TFM for each transitive dependency.
- The helper library is pulled in targeting .NET Standard 2.0, with a string variant metadata reference.
- The ImGui.NET library is pulled in targeting .NET 6 (or whatever), with a span variant metadata reference.
Please consider all implications of having multi-targeted APIs like these. For compatibility, there should always be a lowest common denominator API set to prevent weirdness like this. For maintenance reasons, if this is not rectified and/or more changes like these slip through the cracks, we will sunset our official integrations with ImGui.NET and possibly make our own bindings. I appreciate that everyone's doing this in their free time and may not be able to watch that closely, but so are we and if it becomes more trouble than it's worth we'll just remove it.
I have opened a PR to fix this. The sample now includes a .NET Standard 2.0 library with a single method that calls ImGui.Text
. This currently fails on the master branch, but works on my branch with the updated code generator.
Compatibility with ReadOnlySpan<char>
is also still included, so this doesn't break anything on the other end either.
Please let me know if I've missed anything else, and apologies for the issues.
@zaafar I'll let you handle the version bump and the release if everything looks good to you.
Overall it's looking good, I will merge it and release a new version by end of today.
PR merged, I am going to release a new version tomorrow.
Thanks @zaafar 👍
I don't use Silk.NET, but you can look at the +1s here to determine some testers (I can't see them I'm on mobile)
Thanks for the release! I'll try to get in touch with some users and do my own tests as well.