public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
List <Type> outReturnTypes = new List <Type>();
List <object> returns = new List <object>();
int startIndex = 0;
ParameterInfo[] pis = _mi.GetParameters();
for (startIndex = pis.Length; startIndex > 0; --startIndex)
{
ParameterInfo pi = pis[startIndex - 1];
if ((pi.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out)
{
outReturnTypes.Insert(0, pi.ParameterType);
}
else
{
break;
}
}
object[] uargs = UnwrapArray(args, outReturnTypes.Count);
// Possible varargs
if ((outReturnTypes.Count == 0) && (pis.Length > 0) && (uargs.Length >= pis.Length) && (pis[pis.Length - 1].ParameterType == typeof(object[])))
{
// Copy up to last argument (pis.Length - 1)
object[] xargs = new object[pis.Length];
Array.Copy(uargs, xargs, pis.Length - 1);
// Copy remaining parameters into a trailing array
object[] targs = new object[uargs.Length - pis.Length + 1];
Array.Copy(uargs, pis.Length - 1, targs, 0, targs.Length);
xargs[pis.Length - 1] = targs;
uargs = xargs;
}
object ret = _mi.Invoke(_target, uargs);
if (_mi.ReturnType != typeof(void))
{
returns.Add(DynamicComObjectWrapper.Wrap(_registry, ret, _mi.ReturnType));
}
// Promote out parameters
if (outReturnTypes.Count > 0)
{
for (int i = 0; i < outReturnTypes.Count; ++i)
{
returns.Add(DynamicComObjectWrapper.Wrap(_registry, uargs[startIndex + i], outReturnTypes[i]));
}
}
if (returns.Count == 0)
{
ret = null;
}
else if (returns.Count == 1)
{
ret = returns[0];
}
else
{
ret = Activator.CreateInstance(typeof(Tuple <>).MakeGenericType(returns.Select(o => o != null ? o.GetType() : typeof(object)).ToArray()), returns.ToArray());
}
result = ret;
return(true);
}