{
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
- public abstract class Delegate : ICloneable, ISerializable
+ public abstract partial class Delegate : ICloneable, ISerializable
{
// _target is the object we will invoke on
internal object _target;
DelegateBindingFlags.CaselessMatching);
}
- // Protect the default constructor so you can't build a delegate
- private Delegate()
- {
- }
-
- public object DynamicInvoke(params object[] args)
- {
- // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
- // But to maintain backward compatibility we can't switch to calling an
- // internal overload of DynamicInvokeImpl that takes a stack mark.
- // Fortunately the stack walker skips all the reflection invocation frames including this one.
- // So this method will never be returned by the stack walker as the caller.
- // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
- return DynamicInvokeImpl(args);
- }
-
protected virtual object DynamicInvokeImpl(object[] args)
{
RuntimeMethodHandleInternal method = new RuntimeMethodHandleInternal(GetInvokeMethod());
return GetType().GetHashCode();
}
- public static Delegate Combine(Delegate a, Delegate b)
- {
- if ((object)a == null) // cast to object for a more efficient test
- return b;
-
- return a.CombineImpl(b);
- }
-
- public static Delegate Combine(params Delegate[] delegates)
- {
- if (delegates == null || delegates.Length == 0)
- return null;
-
- Delegate d = delegates[0];
- for (int i = 1; i < delegates.Length; i++)
- d = Combine(d, delegates[i]);
-
- return d;
- }
-
- public virtual Delegate[] GetInvocationList()
- {
- Delegate[] d = new Delegate[1];
- d[0] = this;
- return d;
- }
-
- // This routine will return the method
- public MethodInfo Method
- {
- get
- {
- return GetMethodImpl();
- }
- }
-
protected virtual MethodInfo GetMethodImpl()
{
if ((_methodBase == null) || !(_methodBase is MethodInfo))
}
}
-
- public static Delegate Remove(Delegate source, Delegate value)
- {
- if (source == null)
- return null;
-
- if (value == null)
- return source;
-
- if (!InternalEqualTypes(source, value))
- throw new ArgumentException(SR.Arg_DlgtTypeMis);
-
- return source.RemoveImpl(value);
- }
-
- public static Delegate RemoveAll(Delegate source, Delegate value)
- {
- Delegate newDelegate = null;
-
- do
- {
- newDelegate = source;
- source = Remove(source, value);
- }
- while (newDelegate != source);
-
- return newDelegate;
- }
-
- protected virtual Delegate CombineImpl(Delegate d)
- {
- throw new MulticastNotSupportedException(SR.Multicast_Combine);
- }
-
- protected virtual Delegate RemoveImpl(Delegate d)
- {
- return (d.Equals(this)) ? null : this;
- }
-
-
- public virtual object Clone()
- {
- return MemberwiseClone();
- }
-
- // V1 API.
- public static Delegate CreateDelegate(Type type, object target, string method)
- {
- return CreateDelegate(type, target, method, false, true);
- }
-
- // V1 API.
- public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase)
- {
- return CreateDelegate(type, target, method, ignoreCase, true);
- }
-
// V1 API.
public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure)
{
}
// V1 API.
- public static Delegate CreateDelegate(Type type, Type target, string method)
- {
- return CreateDelegate(type, target, method, false, true);
- }
-
- // V1 API.
- public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase)
- {
- return CreateDelegate(type, target, method, ignoreCase, true);
- }
-
- // V1 API.
public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure)
{
if (type == null)
}
// V2 API.
- public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method)
- {
- return CreateDelegate(type, firstArgument, method, true);
- }
-
- // V2 API.
public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure)
{
// Validate the parameters.
return d;
}
- // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool operator ==(Delegate d1, Delegate d2)
- {
- // Test d2 first to allow branch elimination when inlined for null checks (== null)
- // so it can become a simple test
- if (d2 is null)
- {
- // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
- return (d1 is null) ? true : false;
- }
-
- return ReferenceEquals(d2, d1) ? true : d2.Equals((object)d1);
- }
-
- public static bool operator !=(Delegate d1, Delegate d2)
- {
- // Test d2 first to allow branch elimination when inlined for not null checks (!= null)
- // so it can become a simple test
- if (d2 is null)
- {
- // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
- return (d1 is null) ? false : true;
- }
-
- return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1);
- }
-
- //
- // Implementation of ISerializable
- //
-
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- throw new PlatformNotSupportedException();
- }
-
//
// internal implementation details (FCALLS and utilities)
//
return d;
}
- // V1 API.
- public static Delegate CreateDelegate(Type type, MethodInfo method)
- {
- return CreateDelegate(type, method, true);
- }
-
internal static Delegate CreateDelegateInternal(RuntimeType rtType, RuntimeMethodInfo rtMethod, object firstArgument, DelegateBindingFlags flags)
{
Delegate d = InternalAlloc(rtType);
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+
+namespace System
+{
+ public abstract partial class Delegate : ICloneable, ISerializable
+ {
+ private Delegate()
+ {
+ }
+
+ public virtual object Clone() => MemberwiseClone();
+
+ public static Delegate Combine(Delegate a, Delegate b)
+ {
+ if (a is null)
+ return b;
+
+ return a.CombineImpl(b);
+ }
+
+ public static Delegate Combine(params Delegate[] delegates)
+ {
+ if (delegates is null || delegates.Length == 0)
+ return null;
+
+ Delegate d = delegates [0];
+ for (int i = 1; i < delegates.Length; i++)
+ d = Combine(d, delegates[i]);
+
+ return d;
+ }
+
+ protected virtual Delegate CombineImpl(Delegate d) => throw new MulticastNotSupportedException(SR.Multicast_Combine);
+
+ // V2 api: Creates open or closed delegates to static or instance methods - relaxed signature checking allowed.
+ public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method) => CreateDelegate(type, firstArgument, method, throwOnBindFailure: true);
+
+ // V1 api: Creates open delegates to static or instance methods - relaxed signature checking allowed.
+ public static Delegate CreateDelegate(Type type, MethodInfo method) => CreateDelegate(type, method, throwOnBindFailure: true);
+
+ // V1 api: Creates closed delegates to instance methods only, relaxed signature checking disallowed.
+ public static Delegate CreateDelegate(Type type, object target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true);
+ public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true);
+
+ // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed.
+ public static Delegate CreateDelegate(Type type, Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true);
+ public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true);
+
+ public object DynamicInvoke(params object[] args)
+ {
+ return DynamicInvokeImpl(args);
+ }
+
+ public virtual Delegate[] GetInvocationList() => new Delegate[] { this };
+
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context) => throw new PlatformNotSupportedException();
+
+ public MethodInfo Method => GetMethodImpl();
+
+ protected virtual Delegate RemoveImpl(Delegate d) => d.Equals(this) ? null : this;
+
+ public static Delegate Remove(Delegate source, Delegate value)
+ {
+ if (source == null)
+ return null;
+
+ if (value == null)
+ return source;
+
+ if (!InternalEqualTypes(source, value))
+ throw new ArgumentException(SR.Arg_DlgtTypeMis);
+
+ return source.RemoveImpl(value);
+ }
+
+ public static Delegate RemoveAll(Delegate source, Delegate value)
+ {
+ Delegate newDelegate = null;
+
+ do
+ {
+ newDelegate = source;
+ source = Remove(source, value);
+ }
+ while (newDelegate != source);
+
+ return newDelegate;
+ }
+
+ // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool operator ==(Delegate d1, Delegate d2)
+ {
+ // Test d2 first to allow branch elimination when inlined for null checks (== null)
+ // so it can become a simple test
+ if (d2 is null)
+ {
+ // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
+ return (d1 is null) ? true : false;
+ }
+
+ return ReferenceEquals(d2, d1) || d2.Equals((object)d1);
+ }
+
+ // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool operator !=(Delegate d1, Delegate d2)
+ {
+ // Test d2 first to allow branch elimination when inlined for not null checks (!= null)
+ // so it can become a simple test
+ if (d2 is null)
+ {
+ // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
+ return (d1 is null) ? false : true;
+ }
+
+ return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1);
+ }
+ }
+}
\ No newline at end of file