| File: FrameworkFork\System.ServiceModel\System\ServiceModel\Dispatcher\InvokerUtil.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; namespace System.ServiceModel.Dispatcher { internal delegate object InvokeDelegate(object target, object[] inputs, object[] outputs); internal sealed class InvokerUtil { private readonly CriticalHelper _helper; public InvokerUtil() { _helper = new CriticalHelper(); } internal InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount) { return _helper.GenerateInvokeDelegate(method, out inputParameterCount, out outputParameterCount); } private class CriticalHelper { internal InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount) { ParameterInfo[] parameters = method.GetParameters(); bool returnsValue = method.ReturnType != typeof(void); var inputCount = parameters.Length; inputParameterCount = inputCount; var outputParamPositions = new List<int>(); for (int i = 0; i < inputParameterCount; i++) { if (parameters[i].ParameterType.IsByRef) { outputParamPositions.Add(i); } } var outputPos = outputParamPositions.ToArray(); outputParameterCount = outputPos.Length; InvokeDelegate lambda = delegate (object target, object[] inputs, object[] outputs) { object[] inputsLocal = null; if (inputCount > 0) { inputsLocal = new object[inputCount]; for (var i = 0; i < inputCount; i++) { inputsLocal[i] = inputs[i]; } } object result = null; if (returnsValue) { result = method.Invoke(target, inputsLocal); } else { method.Invoke(target, inputsLocal); } for (var i = 0; i < outputPos.Length; i++) { outputs[i] = inputs[outputPos[i]]; } return result; }; return lambda; } } } }