diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs index 521000b056cdad..d5727eb2ce13b4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs @@ -172,7 +172,7 @@ internal void StoreDynamicMethod(MethodInfo dynamicMethod) // This method will combine this delegate with the passed delegate // to form a new delegate. - protected sealed override Delegate CombineImpl(Delegate? follow) + internal new Delegate CombineImpl(Delegate? follow) { if (follow is null) return this; @@ -290,21 +290,21 @@ private static bool EqualInvocationLists(object[] a, object[] b, int start, int // look at the invocation list.) If this is found we remove it from // this list and return a new delegate. If its not found a copy of the // current list is returned. - protected sealed override Delegate? RemoveImpl(Delegate value) + internal new Delegate? RemoveImpl(Delegate? value) { // There is a special case were we are removing using a delegate as // the value we need to check for this case // MulticastDelegate? v = value as MulticastDelegate; - if (v == null) return this; + if (v._invocationList is not object[]) { if (_invocationList is not object[] invocationList) { // they are both not real Multicast - if (Equals(value)) + if (Equals(v)) return null; } else @@ -312,7 +312,7 @@ private static bool EqualInvocationLists(object[] a, object[] b, int start, int int invocationCount = (int)_invocationCount; for (int i = invocationCount; --i >= 0;) { - if (value.Equals(invocationList[i])) + if (v.Equals(invocationList[i])) { if (invocationCount == 2) { @@ -362,7 +362,7 @@ private static bool EqualInvocationLists(object[] a, object[] b, int start, int } // This method returns the Invocation list of this multicast delegate. - public sealed override Delegate[] GetInvocationList() + internal new Delegate[] GetInvocationList() { Delegate[] del; if (_invocationList is not object[] invocationList) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs index b59e007cee8d33..0f3d189050dfd6 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs @@ -484,7 +484,7 @@ private static bool TrySetSlot(Wrapper[] a, int index, Delegate o) // This method will combine this delegate with the passed delegate // to form a new delegate. - protected virtual Delegate CombineImpl(Delegate? d) + protected Delegate CombineImpl(Delegate? d) { if (d is null) return this; @@ -602,7 +602,7 @@ private static bool EqualInvocationLists(Wrapper[] a, Wrapper[] b, int start, in // look at the invocation list.) If this is found we remove it from // this list and return a new delegate. If its not found a copy of the // current list is returned. - protected virtual Delegate? RemoveImpl(Delegate d) + protected Delegate? RemoveImpl(Delegate? d) { // There is a special case were we are removing using a delegate as // the value we need to check for this case @@ -671,7 +671,7 @@ private static bool EqualInvocationLists(Wrapper[] a, Wrapper[] b, int start, in return this; } - public virtual Delegate[] GetInvocationList() + public Delegate[] GetInvocationList() { if (_helperObject is Wrapper[] invocationList) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs index 6efa9f48554fad..0e4c4d28ec5122 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs @@ -68,11 +68,11 @@ public abstract partial class Delegate : ICloneable, ISerializable public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; #if !NATIVEAOT - protected virtual Delegate CombineImpl(Delegate? d) => throw new MulticastNotSupportedException(SR.Multicast_Combine); + protected Delegate CombineImpl(Delegate? d) => Unsafe.As(this).CombineImpl(d); - protected virtual Delegate? RemoveImpl(Delegate d) => d.Equals(this) ? null : this; + protected Delegate? RemoveImpl(Delegate? d) => Unsafe.As(this).RemoveImpl(d); - public virtual Delegate[] GetInvocationList() => [this]; + public Delegate[] GetInvocationList() => Unsafe.As(this).GetInvocationList(); /// /// Gets a value that indicates whether the has a single invocation target. diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index a5ba94532bf8e5..22815eb1d97c25 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2342,7 +2342,7 @@ protected Delegate([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAt public static System.Delegate? Combine(System.Delegate? a, System.Delegate? b) { throw null; } public static System.Delegate? Combine(params System.Delegate?[]? delegates) { throw null; } public static System.Delegate? Combine(params System.ReadOnlySpan delegates) { throw null; } - protected virtual System.Delegate CombineImpl(System.Delegate? d) { throw null; } + protected System.Delegate CombineImpl(System.Delegate? d) { throw null; } public static System.Delegate CreateDelegate(System.Type type, object? firstArgument, System.Reflection.MethodInfo method) { throw null; } public static System.Delegate? CreateDelegate(System.Type type, object? firstArgument, System.Reflection.MethodInfo method, bool throwOnBindFailure) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] @@ -2361,7 +2361,7 @@ protected Delegate([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAt public static System.Delegate.InvocationListEnumerator EnumerateInvocationList(TDelegate? d) where TDelegate : System.Delegate { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public override int GetHashCode() { throw null; } - public virtual System.Delegate[] GetInvocationList() { throw null; } + public System.Delegate[] GetInvocationList() { throw null; } protected virtual System.Reflection.MethodInfo GetMethodImpl() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] @@ -2370,7 +2370,7 @@ public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo public static bool operator !=(System.Delegate? d1, System.Delegate? d2) { throw null; } public static System.Delegate? Remove(System.Delegate? source, System.Delegate? value) { throw null; } public static System.Delegate? RemoveAll(System.Delegate? source, System.Delegate? value) { throw null; } - protected virtual System.Delegate? RemoveImpl(System.Delegate d) { throw null; } + protected System.Delegate? RemoveImpl(System.Delegate? d) { throw null; } public partial struct InvocationListEnumerator where TDelegate : System.Delegate { public TDelegate Current { get { throw null; } } @@ -4793,17 +4793,14 @@ public abstract partial class MulticastDelegate : System.Delegate [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected MulticastDelegate(object target, string method) : base (default(object), default(string)) { } protected MulticastDelegate([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.AllMethods)] System.Type target, string method) : base (default(object), default(string)) { } - protected sealed override System.Delegate CombineImpl(System.Delegate? follow) { throw null; } public sealed override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public sealed override int GetHashCode() { throw null; } - public sealed override System.Delegate[] GetInvocationList() { throw null; } protected override System.Reflection.MethodInfo GetMethodImpl() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId="SYSLIB0051", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public static bool operator ==(System.MulticastDelegate? d1, System.MulticastDelegate? d2) { throw null; } public static bool operator !=(System.MulticastDelegate? d1, System.MulticastDelegate? d2) { throw null; } - protected sealed override System.Delegate? RemoveImpl(System.Delegate value) { throw null; } } public sealed partial class MulticastNotSupportedException : System.SystemException { diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 95960d00eda311..065f3eff037105 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -337,6 +337,60 @@ net10.0/System.Runtime.Intrinsics.dll net11.0/System.Runtime.Intrinsics.dll + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + net10.0/mscorlib.dll + net11.0/mscorlib.dll + + + CP0012 + M:System.Delegate.GetInvocationList + net10.0/mscorlib.dll + net11.0/mscorlib.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + net10.0/mscorlib.dll + net11.0/mscorlib.dll + + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + net10.0/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.GetInvocationList + net10.0/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + net10.0/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + net10.0/System.Runtime.dll + net11.0/System.Runtime.dll + + + CP0012 + M:System.Delegate.GetInvocationList + net10.0/System.Runtime.dll + net11.0/System.Runtime.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + net10.0/System.Runtime.dll + net11.0/System.Runtime.dll + CP0014 M:System.Security.Cryptography.X509Certificates.PublicKey.#ctor(System.Security.Cryptography.MLDsa):[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] diff --git a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml index 8d18b718a612ae..e33c2d47f78f67 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml @@ -1,4 +1,4 @@ - + @@ -229,6 +229,60 @@ netstandard2.0/System.Xml.dll net11.0/System.Xml.dll + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + netstandard2.0/mscorlib.dll + net11.0/mscorlib.dll + + + CP0012 + M:System.Delegate.GetInvocationList + netstandard2.0/mscorlib.dll + net11.0/mscorlib.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + netstandard2.0/mscorlib.dll + net11.0/mscorlib.dll + + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + netstandard2.0/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.GetInvocationList + netstandard2.0/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + netstandard2.0/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + netstandard2.0/System.Runtime.dll + net11.0/System.Runtime.dll + + + CP0012 + M:System.Delegate.GetInvocationList + netstandard2.0/System.Runtime.dll + net11.0/System.Runtime.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + netstandard2.0/System.Runtime.dll + net11.0/System.Runtime.dll + CP0014 M:System.Collections.IEnumerable.GetEnumerator:[T:System.Runtime.InteropServices.DispIdAttribute] diff --git a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml index a11fe6cb50a601..3c2c66c349e466 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml @@ -1,6 +1,24 @@ - + + + CP0012 + M:System.Delegate.CombineImpl(System.Delegate) + netstandard2.1/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.GetInvocationList + netstandard2.1/netstandard.dll + net11.0/netstandard.dll + + + CP0012 + M:System.Delegate.RemoveImpl(System.Delegate) + netstandard2.1/netstandard.dll + net11.0/netstandard.dll + CP0014 E:System.Diagnostics.Process.ErrorDataReceived:[T:System.ComponentModel.BrowsableAttribute] @@ -853,6 +871,12 @@ netstandard2.1/netstandard.dll net11.0/netstandard.dll + + CP0015 + T:System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute:[T:System.AttributeUsageAttribute] + netstandard2.1/netstandard.dll + net11.0/netstandard.dll + CP0015 T:System.Runtime.CompilerServices.AsyncMethodBuilderAttribute:[T:System.AttributeUsageAttribute] @@ -1003,10 +1027,4 @@ netstandard2.1/netstandard.dll net11.0/netstandard.dll - - CP0015 - T:System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute:[T:System.AttributeUsageAttribute] - netstandard2.1/netstandard.dll - net11.0/netstandard.dll - \ No newline at end of file diff --git a/src/mono/System.Private.CoreLib/src/System/MulticastDelegate.Mono.cs b/src/mono/System.Private.CoreLib/src/System/MulticastDelegate.Mono.cs index 47fb79aa3cdfa7..c026cf46a88539 100644 --- a/src/mono/System.Private.CoreLib/src/System/MulticastDelegate.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/MulticastDelegate.Mono.cs @@ -94,7 +94,7 @@ protected override MethodInfo GetMethodImpl() // Return, in order of invocation, the invocation list // of a MulticastDelegate // - public sealed override Delegate[] GetInvocationList() + internal new Delegate[] GetInvocationList() { if (delegates != null) return (Delegate[])delegates.Clone(); @@ -126,7 +126,7 @@ public sealed override Delegate[] GetInvocationList() // thing should have better been a simple System.Delegate class. // Compiler generated delegates are always MulticastDelegates. // - protected sealed override Delegate CombineImpl(Delegate? follow) + internal new Delegate CombineImpl(Delegate? follow) { if (follow == null) return this; @@ -197,7 +197,7 @@ private static int LastIndexOf(Delegate[] haystack, Delegate[] needle) return -1; } - protected sealed override Delegate? RemoveImpl(Delegate value) + internal new Delegate? RemoveImpl(Delegate? value) { if (value == null) return this;