public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
if (binder == null)
binder = Binder.DefaultBinder;
/*Avoid allocating an array every time*/
ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length))
throw new TargetParameterCountException ("parameters do not match signature");
if ((invokeAttr & BindingFlags.ExactBinding) == 0) {
if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
throw new ArgumentException ("failed to convert parameters");
} else {
for (int i = 0; i < pinfo.Length; i++)
if (parameters[i].GetType() != pinfo[i].ParameterType)
throw new ArgumentException ("parameters do not match signature");
}
#if !NET_2_1
if (SecurityManager.SecurityEnabled) {
// sadly Attributes doesn't tell us which kind of security action this is so
// we must do it the hard way - and it also means that we can skip calling
// Attribute (which is another an icall)
SecurityManager.ReflectedLinkDemandInvoke (this);
}
#endif
#if NET_2_0
if (ContainsGenericParameters)
throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
#endif
Exception exc;
object o = null;
try {
// The ex argument is used to distinguish exceptions thrown by the icall
// from the exceptions thrown by the called method (which need to be
// wrapped in TargetInvocationException).
o = InternalInvoke (obj, parameters, out exc);
#if NET_2_0
} catch (ThreadAbortException) {
throw;
#endif
#if NET_2_1
} catch (MethodAccessException) {
throw;
#endif
} catch (Exception e) {
throw new TargetInvocationException (e);
}
if (exc != null)
throw exc;
return o;
}