Пример #1
0
        public DispatchResult Dispatch(object target, params object[] args)
        {
            if (TargetOrArgumentIsNull(target, args))
            {
                return(new DispatchResult(DispatchStatus.NoMatch));
            }

            MethodInvoker method = _dispatchTable.Match(args);

            if (method != null)
            {
                return(InvokeMethod(method, target, args));
            }

            try
            {
                MethodInfo info = TryReflectionMatch(args);

                if (info.MethodHandle != _multiMethod.MethodHandle)                 // always use MethodInfo.MethodHandle to compare!
                {
                    method = MethodInvokerHelper.CreateInvoker(info);
                }
                else
                {
                    method = delegate
                    {
                        return(new DispatchResult(DispatchStatus.NoMatch));
                    };
                }
            }
            catch (AmbiguousMatchException)
            {
                method = delegate
                {
                    return(new DispatchResult(DispatchStatus.AmbiguousMatch));
                };
            }

            _dispatchTable.Add(args, method);

            DispatchResult result = InvokeMethod(method, target, args);

            result.IsDynamicInvoke = true;

            return(result);
        }
Пример #2
0
        private Dispatcher(Type implementation, MethodInfo multiMethod, bool is32BitPlatform)
        {
            Constraints.CheckImplementationType(implementation);
            Constraints.CheckMultiMethod(multiMethod);

            int argumentCount = multiMethod.GetParameters().Length;

            DispatchTable dispatchTable = new DispatchTable(argumentCount, is32BitPlatform);

            Type currentType = implementation;

            while (currentType != typeof(object))
            {
                MethodInfo[] methods = currentType.GetMethods(
                    DefaultBindingFlags | BindingFlags.DeclaredOnly);

                foreach (MethodInfo candidate in methods)
                {
                    if (candidate.MethodHandle != multiMethod.MethodHandle &&
                        candidate.Name == multiMethod.Name &&
                        candidate.GetParameters().Length == argumentCount &&
                        !candidate.ContainsGenericParameters &&
                        !HasInterfaceOrAbstractParameter(candidate))
                    {
                        Type[] types = GetParameterTypes(candidate);

                        //System.Diagnostics.Debug.WriteLine(
                        //    string.Format("{0}.{1}", candidate.DeclaringType, candidate));

                        dispatchTable.InternalAdd(types,
                                                  MethodInvokerHelper.CreateInvoker(candidate));
                    }
                }

                currentType = currentType.BaseType;
            }

            _implementation = implementation;
            _multiMethod    = multiMethod;
            _dispatchTable  = dispatchTable;
        }