Polyfill icon indicating copy to clipboard operation
Polyfill copied to clipboard

Namespace of created extension methods

Open manfred-brands opened this issue 4 months ago • 15 comments

I have a NetStandard20.Extension project at work which is a subset of what Polyfill does and I would like to replace mine with Polyfill and contribute to that instead of the private project.

Is the feature request related to a problem

Polyfill(Lib) is not a drop in package to compile later .NET methods targeting older TargetFrameworks.

The main reason is that the namespace used by Polyfill doesn't match the namespace to use for later frameworks.

E.g. later code does using System.Linq for ToHashSet, but when using Polyfill it requires using Polyfills. Yes the latter could be added as implicit usings, but then we get an IDE0005 about the non-used using System.Linq. Putting a conditional around that defeats the purpose of Polyfill.

Describe the solution

Put all extension methods in the namespace appropriate for later TargetFrameworks. IEnumerable<T>.ToHashSet should be in System.Linq StringBuilder.Appendshould be inSystem.Text`

This approach is already used for other types like: Index, Range and the Nullable attributes.

Describe alternatives considered

Only use implict usings. Our coding guidelines do not allow this as we prefer to see what is pulled in by a class.

Additional context

To allow phasing out our own NetStandard20.Extensions library and contribute to Polyfill instead.

manfred-brands avatar Jul 25 '25 09:07 manfred-brands

Our coding guidelines do not allow this as we prefer to see what is pulled in by a class.

doesnt moving extensions to the same namespace as the type contravene this? it is effectively the same outcome

would a compromise be adding the following to your GlobalUsings.cs

global using Polyfills;

SimonCropp avatar Jul 26 '25 10:07 SimonCropp

As an example.

We have a using System.Linq; to indicate the use of that set of methods.

As I said above, for older targets I would get an IDE0005 about the non-used using System.Linq; because the implementation is in the Polyfills namespace.

My aim is that I can use the same modern overloads regardless of target framework and have no conditional compilation or restrictions.

manfred-brands avatar Jul 26 '25 10:07 manfred-brands

so you are proposing a class per namespace that is being extended?

so

namespace System.Linq;
public static class LinqExtensions
{
...
}

SimonCropp avatar Jul 27 '25 22:07 SimonCropp

so you are proposing a class per namespace that is being extended?

Yes, indeed.

manfred-brands avatar Jul 27 '25 23:07 manfred-brands

can u share a full code sample for your above "IDE0005 about the non-used using System.Linq; " case

SimonCropp avatar Jul 28 '25 06:07 SimonCropp

Here is one: Example.zip

Image

The build fails for the net48 build because it uses the Polyfills namespace to resolve the extension method but the net8.0 build is using the System.Linq namespace.

$ dotnet build
  Determining projects to restore...
  Restored C:\Users\m.brands\Downloads\Example\Example.csproj (in 215 ms).
C:\Users\m.brands\Downloads\Example\Partitioner.cs(2,1): error IDE0005: Using directive is unnecessary. (https://learn.
microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0005) [C:\Users\m.brands\Downloads\Example\Example.cspro
j::TargetFramework=net48]
  Example -> C:\Users\m.brands\Downloads\Example\bin\Debug\net8.0\Example.dll

Build FAILED.

Matching the namespace to the later implementation also then matches the documentation from Microsoft.

manfred-brands avatar Jul 28 '25 10:07 manfred-brands

Have you considered just moving your using System.Linq to a Usings.cs or part of the csproj file? That would solve your problems.

patriksvensson avatar Aug 03 '25 12:08 patriksvensson

Have you considered just moving your using System.Linq to a Usings.cs or part of the csproj file? That would solve your problems.

As said before that is against our coding guidelines as we want to see what code is pulled in for a file.

The main point is to get a drop in library to fill the gaps between older and newer target frameworks

manfred-brands avatar Aug 03 '25 12:08 manfred-brands

As said before that is against our coding guidelines as we want to see what code is pulled in for a file.

With respect, this is the same argument that was used against LINQ in the first place: "I want to see what the code is doing."

Make a Using exception for System.Linq because it's pervasive and well-understood.

dahlbyk avatar Aug 04 '25 00:08 dahlbyk

If you declare the using in the csproj or directory.build.props you shouldn't have the ide diagnostic

Evangelink avatar Aug 04 '25 03:08 Evangelink

System.Linq is just an example. Yes that one could be considered global. But not System.Net.Http

I know it can be done, we just don't want to.

Following the opinions here, why did Microsoft create different namespace if you hide them all anyhow with global usings. They could as well have put everything in System.

What would have been even nicer is if Microsoft had maintained the NuGet package for System.Linq, etc. like they do for System.Collections.Immutable. That way we can use the latest API for all target frameworks, especially as most library code does not need CLI support.

Polyfill code is great to fill that gap and it already uses different files. But because 91 files of them are all the same class, VS hangs for a while when opening one of them.

I think it would be nicer to have different static classes per namespace. The actual Polyfill code would not change much except for the namespace declaration. We can keep the same class name.

This change wouldn't affect any other users that already use global usings. I'm willing to contribute if this approach is acceptable.

manfred-brands avatar Aug 04 '25 04:08 manfred-brands

But because 91 files of them are all the same class, VS hangs for a while when opening one of them.

can u elaborate on that?

SimonCropp avatar Aug 04 '25 04:08 SimonCropp

But because 91 files of them are all the same class, VS hangs for a while when opening one of them.

can u elaborate on that?

After I open the project and open any Polyfill_ file, VS hangs for about 40s. I assume that VS opens all 91 files to get all members of the class, I can only speculate.

Image

If I click anywhere in VS, the VS is unresponsive notification is popping up. My VS is VS Professional 2022 17.14.10.

When the first file is loaded, the others load quickly. After closing all, the file also loads quickly.

manfred-brands avatar Aug 04 '25 06:08 manfred-brands

Make a Using exception for System.Linq because it's pervasive and well-understood.

I'm not making a claim this is the case for the OP, but some libraries implementing alternative LINQs rely on using statements to select an implementation used within a specific file. Not that it's a good thing, but they can totally affect the behavior of the code. In general, when extension methods are involved, using statements stop being a fluff and actually affect what methods are being called.

Furthermore, there're more polyfileld namespaces than just System.Linq. I don't think it's reasonable to expect everyone to add every single namespace to global usings to avoid code quality warnings — if anything, enabling this warning is a statement that the user cares about namespaces more, not less. 😁

Anyway, is there any practical reason to not put polyfills into the real namespaces?

Athari avatar Aug 04 '25 08:08 Athari

i am happy to consider a pull request that makes the namespace change.

it will need to target the branch for the next major version https://github.com/SimonCropp/Polyfill/tree/sdk10Version

SimonCropp avatar Aug 26 '25 23:08 SimonCropp