1

I have 2 methods, one of which works with generic param and other one with regular string. It looks like this :

public static async Task PostAlertAsync(this IQueueService queueService,
    AlertTypes alertType,
    string orgId, 
    AlertDetailsBase details = null)
{
    Guard.ArgumentNotNull(queueService, nameof(queueService));
    Guard.ArgumentNotNullOrEmptyString(orgId, nameof(orgId));

    var alertMessage = BuildAlertQueueMessage(alertType, orgId, details);
    await queueService.SendMessageAsync(alertMessage);
}

public static async Task PostAlertAsync<T>(this IQueueService queueService, 
    AlertTypes alertType, 
    T source,
    AlertDetailsBase details = null, 
    string customSubject = null)
    where T: IAlertSource
{
    Guard.ArgumentNotNull(queueService, nameof(queueService));
    Guard.ArgumentNotNull(source, nameof(source));

    var alertMessage = BuildAlertQueueMessage<T>(alertType, source, details, customSubject);
    await queueService.SendMessageAsync(alertMessage);
}

I wonder, why calling compiling next call result with ambiguity error? String in this case is obviously doesn't implement IAlertSource

QueueServiceCollection.Alerts.PostAlertAsync(AlertTypes.AzureAdDsProvisionCompleted, orgId);

Any ideas? Thanks.

pfx
  • 20,323
  • 43
  • 37
  • 57
Olha Shumeliuk
  • 720
  • 7
  • 14
  • 1
    You have default parameters. The compiler doesn't know which version of the method you are attempting to use defaults for. – Kenneth K. Oct 31 '18 at 14:43
  • @KennethK. yes, and also I have required params. Which in second method are not applicable to the call, because string is not IAlertSource – Olha Shumeliuk Oct 31 '18 at 14:45

1 Answers1

2

Simply put: where restrictions are not used while determining which method overload is to be used. So when you ignore that information it becomes not obvious which overload to use. You might argue that exact mach is better but it is not. Both methods can be called using string as parameter if you disregard this information.

Rafal
  • 12,391
  • 32
  • 54
  • 1
    Related article by Eric Lippert: [Constraints are not part of the signature](https://blogs.msdn.microsoft.com/ericlippert/2009/12/10/constraints-are-not-part-of-the-signature/) – Peter B Oct 31 '18 at 14:53
  • But why, if I get rid of optional parameters, it resolve correctly? – Alessandro D'Andria Oct 31 '18 at 14:54
  • @AlessandroD'Andria its not about optional parameters its about generic type parameter and it is how they decided to implement it. As simple as someone decided its not worth the effort and complexity. – Rafal Oct 31 '18 at 14:57
  • @Rafal maybe I lost something, but if you remove optional parameters from both method it resolve to the right overload. – Alessandro D'Andria Oct 31 '18 at 15:33
  • @AlessandroD'Andria actually you are correct about the optional parameters (small surprise for me :)). Yet my answer stands I is just how they did it nothing more. – Rafal Nov 02 '18 at 07:43