private void GenerateAsyncOperation(TypeBuilder typeBuilder, MethodInfo methodInfo, string serviceContractNamespace) { if (IsAsyncOperation(methodInfo)) { // Don't generate Async version of operation contracts that already return a "Task". // Otherwise something like "Task<int> GetFooAsync()" would be complemented by // "Task<Task<int>> GetFooAsyncAsync()" - pointless. return; } var parameters = methodInfo.GetParameters(); var parameterTypes = parameters.Select(p => p.ParameterType).ToArray(); var requiredCustomModifiers = parameters.Select(p => p.GetRequiredCustomModifiers()).ToArray(); var optionalCustomModifiers = parameters.Select(p => p.GetOptionalCustomModifiers()).ToArray(); Type[] returnTypeRequiredCustomModifiers = Type.EmptyTypes; Type[] returnTypeOptionalCustomModifiers = Type.EmptyTypes; if (methodInfo.ReturnParameter != null) { returnTypeRequiredCustomModifiers = methodInfo.ReturnParameter.GetRequiredCustomModifiers(); returnTypeOptionalCustomModifiers = methodInfo.ReturnParameter.GetOptionalCustomModifiers(); } var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name + "Async", GeneratorHelpers.GetInterfaceMethodAttributes(), CallingConventions.Standard, methodInfo.ReturnType == typeof(void) ? typeof(Task) : typeof(Task <>).MakeGenericType(methodInfo.ReturnType), returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); for (var i = 0; i < parameters.Length; ++i) { var parameter = parameters[i]; var parameterBuilder = methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name); if (((int)parameter.Attributes & (int)ParameterAttributes.HasDefault) != 0) { parameterBuilder.SetConstant(parameter.RawDefaultValue); } foreach (var attribute in parameter.BuildCustomAttributes()) { parameterBuilder.SetCustomAttribute(attribute); } } bool isOneWay = IsOnewayOperation(methodInfo); foreach (var attribute in methodInfo.BuildCustomAttributes(serviceContractNamespace, isOneWay)) { methodBuilder.SetCustomAttribute(attribute); } }