/// <summary> /// Invokes the method bound to target, with double dispatch /// </summary> public static TResult SurrogateInvoke <T, TResult>(this object target, Func <T, TResult> method, T arg, Func <TResult> orElse, TResult defaultResult) { target = target ?? throw new ArgumentNullException(nameof(target)); method = method ?? throw new ArgumentNullException(nameof(method)); if (!ReferenceEquals(target, method.Target) && !target.GetType().IsValueType) { throw new InvalidOperationException($"{nameof(method)} must be bound to {nameof(target)}"); } return(DoubleDispatchObject.CreateSurrogate(method, default(T), orElse, defaultResult).Invoke(arg)); }
/// <summary> /// Invokes the method bound to target, with double dispatch /// </summary> public static void SurrogateInvoke <T>(this object target, Action <T> method, T arg, Action orElse) { target = target ?? throw new ArgumentNullException(nameof(target)); method = method ?? throw new ArgumentNullException(nameof(method)); if (!ReferenceEquals(target, method.Target) && !target.GetType().IsValueType) { throw new InvalidOperationException($"{nameof(method)} must be bound to {nameof(target)}"); } DoubleDispatchObject.CreateSurrogate(method, default(T), orElse).Invoke(arg); }
public static DoubleDispatchObject EnsureThreadSafe(this object target, ref DoubleDispatchObject dispatchObject) => EnsureThreadSafe(target, ref dispatchObject, obj => new DoubleDispatchObject(obj));