/// <summary> /// Creates a surrogate of the function delegate, which enables double dispatch in the concrete type of its target /// </summary> public static Func <T, TResult> CreateSurrogate <T, TResult>(Func <T, TResult> function, T prototype, Func <TResult> orElse, TResult defaultResult) { function = function ?? throw new ArgumentNullException(nameof(function)); var target = function.Target ?? throw new ArgumentException("must be bound", nameof(function)); var dispatch = new DoubleDispatchObject(target); var methodName = function.GetMethodInfo().Name; Func <T, TResult> surrogate = arg => dispatch.Via(methodName, arg, orElse, defaultResult); return(surrogate); }
/// <summary> /// Creates a surrogate of the action delegate, which enables double dispatch in the concrete type of its target /// </summary> public static Action <T> CreateSurrogate <T>(Action <T> action, T prototype, Action orElse) { action = action ?? throw new ArgumentNullException(nameof(action)); var target = action.Target ?? throw new ArgumentException("must be bound", nameof(action)); var dispatch = new DoubleDispatchObject(target); var methodName = action.GetMethodInfo().Name; Action <T> surrogate = arg => dispatch.Via(methodName, arg, orElse); return(surrogate); }