diff --git a/apiCount.include.md b/apiCount.include.md index 722c8be32..418befe94 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1 +1 @@ -**API count: 646** \ No newline at end of file +**API count: 647** \ No newline at end of file diff --git a/api_list.include.md b/api_list.include.md index afbd7254f..8ef199ea4 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -805,6 +805,7 @@ #### Type * `MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas?view=net-10.0) + * `MethodInfo? GetMethod(string, int, BindingFlags, Binder?, Type[], ParameterModifier[]?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-reflection-binder-system-type()-system-reflection-parametermodifier())) * `MethodInfo? GetMethod(string, int, BindingFlags, Type[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-type())) * `bool IsAssignableFrom()` * `bool IsAssignableTo(Type?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isassignableto?view=net-10.0) diff --git a/assemblySize.include.md b/assemblySize.include.md index 79b23d98a..d6bd68a72 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -2,16 +2,16 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0 KB | 184.0 KB | +176.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | +| netstandard2.0 | 8.0 KB | 185.5 KB | +177.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | | netstandard2.1 | 8.5 KB | 148.0 KB | +139.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB | -| net461 | 7.0 KB | 189.0 KB | +182.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | -| net462 | 7.0 KB | 189.0 KB | +182.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | -| net47 | 7.0 KB | 189.0 KB | +182.0 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | -| net471 | 8.5 KB | 189.0 KB | +180.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | -| net472 | 8.5 KB | 187.5 KB | +179.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | -| net48 | 8.5 KB | 187.5 KB | +179.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | -| net481 | 8.5 KB | 187.5 KB | +179.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | -| netcoreapp2.0 | 9.0 KB | 165.0 KB | +156.0 KB | +8.0 KB | +5.0 KB | +8.5 KB | +13.5 KB | +| net461 | 7.0 KB | 190.5 KB | +183.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | +| net462 | 7.0 KB | 190.5 KB | +183.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | +| net47 | 7.0 KB | 190.0 KB | +183.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | +| net471 | 8.5 KB | 190.0 KB | +181.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB | +| net472 | 8.5 KB | 189.0 KB | +180.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | +| net48 | 8.5 KB | 189.0 KB | +180.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | +| net481 | 8.5 KB | 189.0 KB | +180.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +13.5 KB | +| netcoreapp2.0 | 9.0 KB | 166.0 KB | +157.0 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB | | netcoreapp2.1 | 9.0 KB | 157.5 KB | +148.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB | | netcoreapp2.2 | 9.0 KB | 157.5 KB | +148.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB | | netcoreapp3.0 | 9.5 KB | 151.5 KB | +142.0 KB | +8.5 KB | +5.5 KB | +9.5 KB | +14.0 KB | @@ -28,23 +28,23 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0 KB | 292.0 KB | +284.0 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| netstandard2.1 | 8.5 KB | 236.7 KB | +228.2 KB | +16.4 KB | +6.5 KB | +14.4 KB | +19.9 KB | -| net461 | 7.0 KB | 297.5 KB | +290.5 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| net462 | 7.0 KB | 297.5 KB | +290.5 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| net47 | 7.0 KB | 297.2 KB | +290.2 KB | +16.4 KB | +6.5 KB | +14.4 KB | +19.4 KB | -| net471 | 8.5 KB | 297.2 KB | +288.7 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| net472 | 8.5 KB | 294.6 KB | +286.1 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| net48 | 8.5 KB | 294.6 KB | +286.1 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| net481 | 8.5 KB | 294.6 KB | +286.1 KB | +16.4 KB | +7.0 KB | +14.4 KB | +19.9 KB | -| netcoreapp2.0 | 9.0 KB | 263.6 KB | +254.6 KB | +15.9 KB | +6.5 KB | +13.9 KB | +19.4 KB | -| netcoreapp2.1 | 9.0 KB | 249.9 KB | +240.9 KB | +16.4 KB | +6.5 KB | +14.4 KB | +19.9 KB | -| netcoreapp2.2 | 9.0 KB | 249.9 KB | +240.9 KB | +16.4 KB | +6.5 KB | +14.4 KB | +19.9 KB | -| netcoreapp3.0 | 9.5 KB | 236.5 KB | +227.0 KB | +16.4 KB | +7.0 KB | +14.9 KB | +19.9 KB | -| netcoreapp3.1 | 9.5 KB | 235.0 KB | +225.5 KB | +16.4 KB | +6.5 KB | +14.4 KB | +19.9 KB | -| net5.0 | 9.5 KB | 210.2 KB | +200.7 KB | +16.4 KB | +6.5 KB | +14.4 KB | +19.4 KB | -| net6.0 | 10.0 KB | 165.1 KB | +155.1 KB | +16.9 KB | +6.4 KB | +1.6 KB | +4.5 KB | -| net7.0 | 10.0 KB | 129.5 KB | +119.5 KB | +16.8 KB | +6.3 KB | +2.1 KB | +4.5 KB | -| net8.0 | 9.5 KB | 102.6 KB | +93.1 KB | +16.3 KB | +1.8 KB | +1.6 KB | +4.5 KB | -| net9.0 | 10.0 KB | 62.2 KB | +52.2 KB | +16.8 KB | +1.7 KB | +2.1 KB | +5.0 KB | -| net10.0 | 10.0 KB | 48.5 KB | +38.5 KB | +17.3 KB | +2.2 KB | +2.1 KB | +5.0 KB | +| netstandard2.0 | 8.0 KB | 292.1 KB | +284.1 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| netstandard2.1 | 8.5 KB | 235.3 KB | +226.8 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB | +| net461 | 7.0 KB | 297.6 KB | +290.6 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| net462 | 7.0 KB | 297.6 KB | +290.6 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| net47 | 7.0 KB | 296.8 KB | +289.8 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB | +| net471 | 8.5 KB | 296.8 KB | +288.3 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB | +| net472 | 8.5 KB | 294.7 KB | +286.2 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| net48 | 8.5 KB | 294.7 KB | +286.2 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| net481 | 8.5 KB | 294.7 KB | +286.2 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.3 KB | +| netcoreapp2.0 | 9.0 KB | 263.3 KB | +254.3 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| netcoreapp2.1 | 9.0 KB | 248.4 KB | +239.4 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB | +| netcoreapp2.2 | 9.0 KB | 248.4 KB | +239.4 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB | +| netcoreapp3.0 | 9.5 KB | 235.1 KB | +225.6 KB | +16.2 KB | +6.9 KB | +14.9 KB | +19.8 KB | +| netcoreapp3.1 | 9.5 KB | 233.5 KB | +224.0 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB | +| net5.0 | 9.5 KB | 208.9 KB | +199.4 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB | +| net6.0 | 10.0 KB | 163.9 KB | +153.9 KB | +16.7 KB | +6.4 KB | +1.6 KB | +4.5 KB | +| net7.0 | 10.0 KB | 128.5 KB | +118.5 KB | +16.7 KB | +6.3 KB | +2.1 KB | +4.5 KB | +| net8.0 | 9.5 KB | 101.7 KB | +92.2 KB | +16.2 KB | +1.8 KB | +1.6 KB | +4.5 KB | +| net9.0 | 10.0 KB | 61.5 KB | +51.5 KB | +16.7 KB | +1.6 KB | +2.1 KB | +5.0 KB | +| net10.0 | 10.0 KB | 47.9 KB | +37.9 KB | +17.2 KB | +2.1 KB | +2.1 KB | +5.0 KB | diff --git a/readme.md b/readme.md index e16c72ad8..b3eb26b82 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ The package targets `netstandard2.0` and is designed to support the following ru * `uap10` -**API count: 646** +**API count: 647** **See [Milestones](../../milestones?state=closed) for release notes.** @@ -1250,6 +1250,7 @@ The class `Polyfill` includes the following extension methods: #### Type * `MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas?view=net-10.0) + * `MethodInfo? GetMethod(string, int, BindingFlags, Binder?, Type[], ParameterModifier[]?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-reflection-binder-system-type()-system-reflection-parametermodifier())) * `MethodInfo? GetMethod(string, int, BindingFlags, Type[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-type())) * `bool IsAssignableFrom()` * `bool IsAssignableTo(Type?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isassignableto?view=net-10.0) @@ -1576,7 +1577,7 @@ void ArgumentExceptionExample(Order order, Customer customer, string customerId, this.quantity = quantity; } ``` -snippet source | anchor +snippet source | anchor @@ -1595,7 +1596,7 @@ void EnsureExample(Order order, Customer customer, string customerId, string ema this.quantity = Ensure.NotNegativeOrZero(quantity); } ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 7c5ee41e6..0918bf3a6 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -295,20 +295,26 @@ async Task CancellationTokenSource_Methods() } -#if !NETFRAMEWORK && !NETSTANDARD2_0 && !NETCOREAPP2_0 - class WithGenericMethod + class WithMethods { - public void GenericMethod(string value) - { - } + public void NonGenericMethod(string value) { } + public void GenericMethod(string value) { } + public void GenericMethod(string value, int count) { } } void Type_GetMethod() { - var type = typeof(WithGenericMethod); - type.GetMethod("GenericMethod", 1, BindingFlags.Public, [typeof(string)]); + var type = typeof(WithMethods); + + // Non-generic method + var nonGeneric = type.GetMethod("NonGenericMethod", 0, BindingFlags.Public | BindingFlags.Instance, [typeof(string)]); + + // Generic method with 1 type parameter + var generic1 = type.GetMethod("GenericMethod", 1, BindingFlags.Public | BindingFlags.Instance, [typeof(string)]); + + // Generic method with 2 type parameters + var generic2 = type.GetMethod("GenericMethod", 2, BindingFlags.Public | BindingFlags.Instance, [typeof(string), typeof(int)]); } -#endif void ConcurrentDictionary_Methods() { diff --git a/src/Polyfill/KeyValuePair.cs b/src/Polyfill/KeyValuePair.cs index 0c0c7274b..a25d1b61f 100644 --- a/src/Polyfill/KeyValuePair.cs +++ b/src/Polyfill/KeyValuePair.cs @@ -1,4 +1,4 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 +#if (NETFRAMEWORK || NETSTANDARD2_0) && !WINDOWS_UWP #nullable enable namespace System.Collections.Generic; diff --git a/src/Polyfill/Polyfill_Dictionary.cs b/src/Polyfill/Polyfill_Dictionary.cs index 6a0c34277..54b2fa0b7 100644 --- a/src/Polyfill/Polyfill_Dictionary.cs +++ b/src/Polyfill/Polyfill_Dictionary.cs @@ -16,7 +16,7 @@ public static ReadOnlyDictionary AsReadOnly(this IDi new(target); #endif -#if NETFRAMEWORK || NETSTANDARD2_0 +#if (NETFRAMEWORK || NETSTANDARD2_0) && !WINDOWS_UWP /// /// Attempts to add the specified key and value to the . diff --git a/src/Polyfill/Polyfill_IEnumerable_SkipLast.cs b/src/Polyfill/Polyfill_IEnumerable_SkipLast.cs index 4842c312f..c86ce29df 100644 --- a/src/Polyfill/Polyfill_IEnumerable_SkipLast.cs +++ b/src/Polyfill/Polyfill_IEnumerable_SkipLast.cs @@ -1,4 +1,4 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 +#if (NETFRAMEWORK || NETSTANDARD2_0) && !WINDOWS_UWP namespace Polyfills; diff --git a/src/Polyfill/Polyfill_IEnumerable_TakeLast.cs b/src/Polyfill/Polyfill_IEnumerable_TakeLast.cs index 1ee0c712b..0c4e8d3b2 100644 --- a/src/Polyfill/Polyfill_IEnumerable_TakeLast.cs +++ b/src/Polyfill/Polyfill_IEnumerable_TakeLast.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. -#if NETSTANDARD2_0 || NETFRAMEWORK +#if (NETSTANDARD2_0 || NETFRAMEWORK) && !WINDOWS_UWP namespace Polyfills; diff --git a/src/Polyfill/Polyfill_IReadOnlyDictionary.cs b/src/Polyfill/Polyfill_IReadOnlyDictionary.cs index 524bbdb5e..de2f60f75 100644 --- a/src/Polyfill/Polyfill_IReadOnlyDictionary.cs +++ b/src/Polyfill/Polyfill_IReadOnlyDictionary.cs @@ -1,4 +1,4 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 +#if (NETFRAMEWORK || NETSTANDARD2_0) && !WINDOWS_UWP #pragma warning disable CS8714 namespace Polyfills; diff --git a/src/Polyfill/Polyfill_Type.cs b/src/Polyfill/Polyfill_Type.cs index aa43f7c7c..c5df3bb97 100644 --- a/src/Polyfill/Polyfill_Type.cs +++ b/src/Polyfill/Polyfill_Type.cs @@ -14,13 +14,20 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.Module.Equals(other.Module); #endif -#if !NET9_0_OR_GREATER && !NETFRAMEWORK && !NETSTANDARD2_0 && !NETCOREAPP2_0 - //Link: https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-type()) - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) +#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 || WINDOWS_UWP + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-reflection-binder-system-type()-system-reflection-parametermodifier()) + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) { -#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); -#else var methods = target.GetMethods(bindingAttr); if (genericParameterCount == 0) { @@ -64,10 +71,18 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf bool IsMatch(MethodInfo method) => name == method.Name && method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); -#endif } #endif +#if !NET9_0_OR_GREATER + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=net-10.0#system-type-getmethod(system-string-system-int32-system-reflection-bindingflags-system-type()) + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); +#endif + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Polyfill/StringPolyfill.cs b/src/Polyfill/StringPolyfill.cs index 544ab48cb..aa880e8c2 100644 --- a/src/Polyfill/StringPolyfill.cs +++ b/src/Polyfill/StringPolyfill.cs @@ -178,7 +178,7 @@ public static string Join(string? separator, scoped ReadOnlySpan values string.Join(separator, values.ToArray()); #endif -#if NETSTANDARD2_0 || NETFRAMEWORK +#if (NETSTANDARD2_0 || NETFRAMEWORK) && !WINDOWS_UWP /// /// Concatenates an array of strings, using the specified separator between each member. diff --git a/src/Split/net461/Polyfill_Type.cs b/src/Split/net461/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net461/Polyfill_Type.cs +++ b/src/Split/net461/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net462/Polyfill_Type.cs b/src/Split/net462/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net462/Polyfill_Type.cs +++ b/src/Split/net462/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net47/Polyfill_Type.cs b/src/Split/net47/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net47/Polyfill_Type.cs +++ b/src/Split/net47/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net471/Polyfill_Type.cs b/src/Split/net471/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net471/Polyfill_Type.cs +++ b/src/Split/net471/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net472/Polyfill_Type.cs b/src/Split/net472/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net472/Polyfill_Type.cs +++ b/src/Split/net472/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net48/Polyfill_Type.cs b/src/Split/net48/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net48/Polyfill_Type.cs +++ b/src/Split/net48/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net481/Polyfill_Type.cs b/src/Split/net481/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/net481/Polyfill_Type.cs +++ b/src/Split/net481/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/net5.0/Polyfill_Type.cs b/src/Split/net5.0/Polyfill_Type.cs index a196b2342..bc2f69e2d 100644 --- a/src/Split/net5.0/Polyfill_Type.cs +++ b/src/Split/net5.0/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/net6.0/Polyfill_Type.cs b/src/Split/net6.0/Polyfill_Type.cs index f059a71ba..f70921393 100644 --- a/src/Split/net6.0/Polyfill_Type.cs +++ b/src/Split/net6.0/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/net7.0/Polyfill_Type.cs b/src/Split/net7.0/Polyfill_Type.cs index f059a71ba..f70921393 100644 --- a/src/Split/net7.0/Polyfill_Type.cs +++ b/src/Split/net7.0/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/net8.0/Polyfill_Type.cs b/src/Split/net8.0/Polyfill_Type.cs index f059a71ba..f70921393 100644 --- a/src/Split/net8.0/Polyfill_Type.cs +++ b/src/Split/net8.0/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/netcoreapp2.0/Polyfill_Type.cs b/src/Split/netcoreapp2.0/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/netcoreapp2.0/Polyfill_Type.cs +++ b/src/Split/netcoreapp2.0/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/netcoreapp2.1/Polyfill_Type.cs b/src/Split/netcoreapp2.1/Polyfill_Type.cs index a196b2342..bc2f69e2d 100644 --- a/src/Split/netcoreapp2.1/Polyfill_Type.cs +++ b/src/Split/netcoreapp2.1/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/netcoreapp2.2/Polyfill_Type.cs b/src/Split/netcoreapp2.2/Polyfill_Type.cs index a196b2342..bc2f69e2d 100644 --- a/src/Split/netcoreapp2.2/Polyfill_Type.cs +++ b/src/Split/netcoreapp2.2/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/netcoreapp3.0/Polyfill_Type.cs b/src/Split/netcoreapp3.0/Polyfill_Type.cs index a196b2342..bc2f69e2d 100644 --- a/src/Split/netcoreapp3.0/Polyfill_Type.cs +++ b/src/Split/netcoreapp3.0/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/netcoreapp3.1/Polyfill_Type.cs b/src/Split/netcoreapp3.1/Polyfill_Type.cs index a196b2342..bc2f69e2d 100644 --- a/src/Split/netcoreapp3.1/Polyfill_Type.cs +++ b/src/Split/netcoreapp3.1/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/netstandard2.0/Polyfill_Type.cs b/src/Split/netstandard2.0/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/netstandard2.0/Polyfill_Type.cs +++ b/src/Split/netstandard2.0/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/netstandard2.1/Polyfill_Type.cs b/src/Split/netstandard2.1/Polyfill_Type.cs index a196b2342..bc2f69e2d 100644 --- a/src/Split/netstandard2.1/Polyfill_Type.cs +++ b/src/Split/netstandard2.1/Polyfill_Type.cs @@ -7,10 +7,11 @@ namespace Polyfills; using System.Linq; static partial class Polyfill { - public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) - { - return target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); - } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// diff --git a/src/Split/uap10.0/KeyValuePair.cs b/src/Split/uap10.0/KeyValuePair.cs index ccb009c23..982a722f6 100644 --- a/src/Split/uap10.0/KeyValuePair.cs +++ b/src/Split/uap10.0/KeyValuePair.cs @@ -1,24 +1,4 @@ // #pragma warning disable -#nullable enable -namespace System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -[ExcludeFromCodeCoverage] -[DebuggerNonUserCode] -#if PolyUseEmbeddedAttribute -[global::Microsoft.CodeAnalysis.EmbeddedAttribute] -#endif -// Provides the Create factory method for KeyValuePair. -// https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair?view=net-10.0 -#if PolyPublic -public -#endif -static class KeyValuePair -{ - /// - /// Creates a new key/value pair instance using provided values. - /// - public static KeyValuePair Create(TKey key, TValue value) => - new(key, value); -} +using System.Runtime.CompilerServices; +[assembly: TypeForwardedTo(typeof(System.Collections.Generic.KeyValuePair))] diff --git a/src/Split/uap10.0/Polyfill_Dictionary.cs b/src/Split/uap10.0/Polyfill_Dictionary.cs index e6e0f3b2c..d12a50c7e 100644 --- a/src/Split/uap10.0/Polyfill_Dictionary.cs +++ b/src/Split/uap10.0/Polyfill_Dictionary.cs @@ -13,32 +13,6 @@ public static ReadOnlyDictionary AsReadOnly(this IDi where TKey : notnull => new(target); /// - /// Attempts to add the specified key and value to the . - /// - public static bool TryAdd(this IDictionary target, TKey key, TValue value) - where TKey : notnull - { - if (!target.ContainsKey(key)) - { - target.Add(key, value); - return true; - } - return false; - } - /// - /// Removes the value with the specified key from the , and copies the element - /// to the value parameter. - /// - public static bool Remove( - this IDictionary target, - TKey key, - [MaybeNullWhen(false)] out TValue value) - where TKey : notnull - { - target.TryGetValue(key, out value); - return target.Remove(key); - } - /// /// Ensures that the capacity of this dictionary is at least the specified capacity. If the current capacity is less than capacity, it is increased to at least the specified capacity. /// public static void EnsureCapacity(this Dictionary target, int capacity) diff --git a/src/Split/uap10.0/Polyfill_IEnumerable_SkipLast.cs b/src/Split/uap10.0/Polyfill_IEnumerable_SkipLast.cs deleted file mode 100644 index 4e91eacc8..000000000 --- a/src/Split/uap10.0/Polyfill_IEnumerable_SkipLast.cs +++ /dev/null @@ -1,16 +0,0 @@ -// -#pragma warning disable -namespace Polyfills; -using System.Collections.Generic; -using System.Linq; -static partial class Polyfill -{ - /// - /// Returns a new enumerable collection that contains the elements from source with the last count elements of the - /// source collection omitted. - /// - public static IEnumerable SkipLast( - this IEnumerable target, - int count) => - target.Reverse().Skip(count).Reverse(); -} diff --git a/src/Split/uap10.0/Polyfill_IEnumerable_TakeLast.cs b/src/Split/uap10.0/Polyfill_IEnumerable_TakeLast.cs deleted file mode 100644 index a111c2c34..000000000 --- a/src/Split/uap10.0/Polyfill_IEnumerable_TakeLast.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -#pragma warning disable -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -namespace Polyfills; -using System.Collections.Generic; -static partial class Polyfill -{ - /// - /// Returns a new enumerable collection that contains the last count elements from source. - /// - public static IEnumerable TakeLast(this IEnumerable source, int count) - { - if (count <= 0 || IsEmptyArray(source)) - { - return []; - } - return TakeRangeFromEndIterator( - source, - isStartIndexFromEnd: true, startIndex: count, - isEndIndexFromEnd: true, endIndex: 0); - } -} diff --git a/src/Split/uap10.0/Polyfill_IReadOnlyDictionary.cs b/src/Split/uap10.0/Polyfill_IReadOnlyDictionary.cs deleted file mode 100644 index 3a3a347f0..000000000 --- a/src/Split/uap10.0/Polyfill_IReadOnlyDictionary.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -#pragma warning disable -#pragma warning disable CS8714 -namespace Polyfills; -using System.Collections.Generic; -static partial class Polyfill -{ - /// - /// Tries to get the value associated with the specified key in the dictionary. - /// - public static TValue? GetValueOrDefault(this IReadOnlyDictionary target, TKey key) => - target.GetValueOrDefault(key, default!); - /// - /// Tries to get the value associated with the specified key in the dictionary. - /// - public static TValue GetValueOrDefault( - this IReadOnlyDictionary target, - TKey key, - TValue defaultValue) - where TKey : notnull - { - if (target.TryGetValue(key, out var result)) - { - return result!; - } - return defaultValue; - } -} diff --git a/src/Split/uap10.0/Polyfill_Type.cs b/src/Split/uap10.0/Polyfill_Type.cs index 89faf49ac..5b8fe477a 100644 --- a/src/Split/uap10.0/Polyfill_Type.cs +++ b/src/Split/uap10.0/Polyfill_Type.cs @@ -11,6 +11,62 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, + string name, + int genericParameterCount, + BindingFlags bindingAttr, + Binder? binder, + Type[] types, + ParameterModifier[]? modifiers) + { + var methods = target.GetMethods(bindingAttr); + if (genericParameterCount == 0) + { + foreach (var method in methods) + { + if (method.IsGenericMethod) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + else + { + foreach (var method in methods) + { + if (!method.IsGenericMethod) + { + continue; + } + var genericArguments = method.GetGenericArguments(); + if (genericParameterCount != genericArguments.Length) + { + continue; + } + if (IsMatch(method)) + { + return method; + } + } + } + return null; + bool IsMatch(MethodInfo method) => + name == method.Name && + method.GetParameters().Select(_ => _.ParameterType).SequenceEqual(types); + } + /// + /// Searches for the specified method whose parameters match the specified generic parameter count, argument types and modifiers, using the specified binding constraints. + /// + public static MethodInfo? GetMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type target, string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) => + target.GetMethod(name, genericParameterCount, bindingAttr, null, types, null); + /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// public static bool IsGenericMethodParameter(this Type target) => diff --git a/src/Split/uap10.0/StringPolyfill.cs b/src/Split/uap10.0/StringPolyfill.cs index d5e1e2676..7d8ac7c32 100644 --- a/src/Split/uap10.0/StringPolyfill.cs +++ b/src/Split/uap10.0/StringPolyfill.cs @@ -132,34 +132,6 @@ public static int GetHashCode(ReadOnlySpan value,StringComparison comparis public static string Join(string? separator, scoped ReadOnlySpan values) => string.Join(separator, values.ToArray()); #endif - /// - /// Concatenates an array of strings, using the specified separator between each member. - /// - public static string Join(char separator, params string?[] values) => -#if AllowUnsafeBlocks && FeatureMemory - Join(separator, new ReadOnlySpan(values)); -#else - string.Join(new(separator, 1), values); -#endif - /// - /// Concatenates the string representations of an array of objects, using the specified separator between each member. - /// - public static string Join(char separator, params object?[] values) => - string.Join(new(separator, 1), values); - /// - /// Concatenates the specified elements of a string array, using the specified separator between each element. - /// - public static string Join(char separator, string?[] value, int startIndex, int count) => -#if AllowUnsafeBlocks && FeatureMemory - Join(separator, new ReadOnlySpan(value, startIndex, count)); -#else - string.Join(new(separator, 1), value, startIndex, count); -#endif - /// - /// Concatenates the specified elements of a string array, using the specified separator between each element. - /// - public static string Join(char separator, IEnumerable values) => - string.Join(new(separator, 1), values); #if FeatureMemory /// /// Creates a new string with a specific length and initializes it after creation by using the specified callback.