Пример #1
0
        protected object ConvertToDelegate(object o, Type toType)
        {
            var        toMethodInfo       = toType.GetMethod("Invoke");
            var        toMethodParams     = toMethodInfo.GetParameters();
            var        toMethodParamCount = toMethodParams.Length;
            MethodInfo fromMethod;
            object     fromObject;

            FindMethod(o, toMethodParamCount, out fromObject, out fromMethod);

            // simplest case - when parameters are contravariant and result is covariant
            var toDelegate = Delegate.CreateDelegate(toType, fromObject, fromMethod, false);

            if (toDelegate != null)
            {
                return(toDelegate);
            }

            // use adapter with run-time types conversion
            var adapter = new DelegateAdapter(fromObject, fromMethod);

            foreach (var adapterMethod in adapter.GetType().GetMethods())
            {
                if (adapterMethod.Name == "Invoke" && adapterMethod.GetParameters().Length == toMethodParamCount)
                {
                    var resType      = toMethodInfo.ReturnType != typeof(void) ? toMethodInfo.ReturnType : typeof(object);
                    var genericTypes = new Type[toMethodParamCount + 1];
                    for (int i = 0; i < toMethodParams.Length; i++)
                    {
                        genericTypes[i] = toMethodParams[i].ParameterType;
                    }
                    genericTypes[toMethodParamCount] = resType;                       // last type for result

                    var typedInvokeMethod = adapterMethod.MakeGenericMethod(genericTypes);
                    LogManager.GetLogger(typeof(DelegateConverter)).Write(LogEvent.Info, typedInvokeMethod.ToString());
                    return(Delegate.CreateDelegate(toType, adapter, typedInvokeMethod, true));
                }
            }

            throw new InvalidCastException();
        }