diff --git a/apiCount.include.md b/apiCount.include.md index de0e0a07..5ad1d1a7 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1,17 +1,17 @@ -**API count: 1022** +**API count: 1020** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 969 | -| `net462` | 969 | -| `net47` | 968 | -| `net471` | 967 | -| `net472` | 963 | +| `net461` | 967 | +| `net462` | 967 | +| `net47` | 966 | +| `net471` | 965 | +| `net472` | 961 | | `net48` | 963 | -| `net481` | 963 | -| `netstandard2.0` | 965 | +| `net481` | 961 | +| `netstandard2.0` | 963 | | `netstandard2.1` | 816 | | `netcoreapp2.0` | 886 | | `netcoreapp2.1` | 827 | @@ -25,4 +25,4 @@ | `net9.0` | 184 | | `net10.0` | 131 | | `net11.0` | 58 | -| `uap10.0` | 955 | +| `uap10.0` | 953 | diff --git a/api_list.include.md b/api_list.include.md index e05b0868..1ea76822 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1148,8 +1148,6 @@ * `StringBuilder AppendJoin(string?, object?[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin(system-string-system-object())) * `StringBuilder AppendJoin(string?, string?[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin(system-string-system-string())) * `StringBuilder AppendJoin(char, IEnumerable)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendJoin(char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendJoin(string, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendJoin(string?, IEnumerable)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendLine(StringBuilder, AppendInterpolatedStringHandler)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline?view=net-11.0#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder AppendLine(StringBuilder, IFormatProvider?, AppendInterpolatedStringHandler)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline?view=net-11.0#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) diff --git a/readme.md b/readme.md index 96207037..1f4aca5e 100644 --- a/readme.md +++ b/readme.md @@ -13,20 +13,20 @@ The package targets `netstandard2.0` and is designed to support the following ru * `uap10` -**API count: 1022** +**API count: 1020** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 969 | -| `net462` | 969 | -| `net47` | 968 | -| `net471` | 967 | -| `net472` | 963 | +| `net461` | 967 | +| `net462` | 967 | +| `net47` | 966 | +| `net471` | 965 | +| `net472` | 961 | | `net48` | 963 | -| `net481` | 963 | -| `netstandard2.0` | 965 | +| `net481` | 961 | +| `netstandard2.0` | 963 | | `netstandard2.1` | 816 | | `netcoreapp2.0` | 886 | | `netcoreapp2.1` | 827 | @@ -40,7 +40,7 @@ The package targets `netstandard2.0` and is designed to support the following ru | `net9.0` | 184 | | `net10.0` | 131 | | `net11.0` | 58 | -| `uap10.0` | 955 | +| `uap10.0` | 953 | @@ -1679,8 +1679,6 @@ The class `Polyfill` includes the following extension methods: * `StringBuilder AppendJoin(string?, object?[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin(system-string-system-object())) * `StringBuilder AppendJoin(string?, string?[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin(system-string-system-string())) * `StringBuilder AppendJoin(char, IEnumerable)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendJoin(char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendJoin(string, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendJoin(string?, IEnumerable)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendLine(StringBuilder, AppendInterpolatedStringHandler)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline?view=net-11.0#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder AppendLine(StringBuilder, IFormatProvider?, AppendInterpolatedStringHandler)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline?view=net-11.0#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 1e685df6..73d18480 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ CS1591;NETSDK1138;NU1901;NU1902;NU1903;CA1822;CA1847;CA1861;NU1510;NU1608;NU1109 - 11.0.1 + 11.0.2 1.0.0 Polyfill true diff --git a/src/Polyfill/Polyfill_StringBuilder_AppendJoin.cs b/src/Polyfill/Polyfill_StringBuilder_AppendJoin.cs index 09e39b22..462c1dbf 100644 --- a/src/Polyfill/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Polyfill/Polyfill_StringBuilder_AppendJoin.cs @@ -59,22 +59,6 @@ public static StringBuilder AppendJoin( params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - //Link: https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0))) - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - //Link: https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=net-11.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0))) - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); - static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net461/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net461/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net461/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net461/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net462/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net462/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net462/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net462/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net47/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net47/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net47/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net47/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net471/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net471/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net471/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net471/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net472/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net472/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net472/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net472/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net48/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net48/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net48/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net48/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/net481/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/net481/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/net481/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/net481/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/netstandard2.0/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/netstandard2.0/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/netstandard2.0/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/netstandard2.0/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Split/uap10.0/Polyfill_StringBuilder_AppendJoin.cs b/src/Split/uap10.0/Polyfill_StringBuilder_AppendJoin.cs index e6e18e54..47ab8882 100644 --- a/src/Split/uap10.0/Polyfill_StringBuilder_AppendJoin.cs +++ b/src/Split/uap10.0/Polyfill_StringBuilder_AppendJoin.cs @@ -43,18 +43,6 @@ public static StringBuilder AppendJoin( char separator, params object?[] values) => target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - char separator, - params T[] values) => - target.AppendJoinCore(separator, values); - /// Concatenates and appends the members of a collection, using the specified char separator between each member. - public static StringBuilder AppendJoin( - this StringBuilder target, - string separator, - params T[] values) => - target.AppendJoinCore(separator, values); static StringBuilder AppendJoinCore( this StringBuilder target, char separator, diff --git a/src/Tests/PolyfillTests_StringBuilder.cs b/src/Tests/PolyfillTests_StringBuilder.cs index 0ed51803..3ba5946e 100644 --- a/src/Tests/PolyfillTests_StringBuilder.cs +++ b/src/Tests/PolyfillTests_StringBuilder.cs @@ -175,14 +175,54 @@ public async Task AppendJoin() await AssertAsync(); builder.AppendJoin(',', new object[] {"value1", "value2"}.Select(_ => _)); await AssertAsync(); - // ReSharper disable once RedundantExplicitParamsArrayCreation builder.AppendJoin(',', ["value1", "value2"]); await AssertAsync(); + // A non-array collection must bind to the IEnumerable overload, not be + // captured as a single element of a params array. + List list = ["value1", "value2"]; + builder.AppendJoin(',', list); + await AssertAsync(); + builder.AppendJoin(",", list); + await AssertAsync(); + async Task AssertAsync() { await Assert.That(builder.ToString()).IsEqualTo("value1,value2"); builder.Clear(); } } + + // The BCL has no AppendJoin overload taking a params array of an open generic type. + // Adding one makes it beat AppendJoin(separator, IEnumerable) for any non-array + // collection: the collection is captured as a single element, so AppendJoin(',', list) + // silently appends "System.Collections.Generic.List`1[System.String]" instead of its + // contents. It compiles, so only the output reveals it, and only on the frameworks + // where the polyfill is active. + [Test] + public async Task AppendJoinHasNoGenericParamsOverload() + { + var offenders = typeof(Polyfills.Polyfill) + .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) + .Where(_ => _.Name == "AppendJoin") + .Select(_ => _.GetParameters()) + .Where(_ => _.Length > 0 && IsGenericParamsArray(_[^1])) + .ToList(); + + await Assert.That(offenders).IsEmpty(); + + static bool IsGenericParamsArray(ParameterInfo parameter) + { + if (parameter.ParameterType.GetElementType() is not {IsGenericParameter: true}) + { + return false; + } + + return parameter + .GetCustomAttributes(inherit: false) + .Any(_ => _.GetType().Name is + nameof(ParamArrayAttribute) or + "ParamCollectionAttribute"); + } + } }