protected virtual void AssertReturnTypeCombination(MethodInfo adapterMethod, MethodInfo targetMethod, InvocationTypes targetInvocationType) { Type targetMethodReturnType = targetMethod.ReturnType; switch (targetInvocationType) { case InvocationTypes.Sync: if (AdapterHelper.IsVoid(adapterMethod.ReturnType) && adapterMethod.ReturnType != targetMethodReturnType) { throw new AdapterInterceptorException($"Adapter and target method return types should match if either is void.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.GenericTask: if (!AdapterHelper.IsGenericTask(adapterMethod.ReturnType)) { throw new AdapterInterceptorException($"Adapter and target method return types should both be a generic Task.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.Task: if (adapterMethod.ReturnType != targetMethodReturnType) { throw new AdapterInterceptorException($"Adapter and target method return types should match if target return type is Task.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.GenericValueTask: if (!AdapterHelper.IsGenericValueTask(adapterMethod.ReturnType)) { throw new AdapterInterceptorException($"Adapter and target method return types should both be a generic ValueTask.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.ValueTask: if (!AdapterHelper.IsValueTask(adapterMethod.ReturnType)) { throw new AdapterInterceptorException($"Adapter and target method return types should match if target return type is ValueTask.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; default: throw new NotImplementedException(); } }