【问题标题】:Ambiguity between generic and simple string in params参数中通用字符串和简单字符串之间的歧义
【发布时间】:2023-03-29 23:07:01
【问题描述】:

我有 2 种方法,其中一种适用于通用参数,另一种适用于常规字符串。它看起来像这样:

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);
}

我想知道,为什么调用编译下一个调用结果时出现歧义错误? String 在这种情况下显然没有实现 IAlertSource

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

有什么想法吗?谢谢。

【问题讨论】:

  • 你有默认参数。编译器不知道您尝试将默认值用于哪个版本的方法。
  • @KennethK。是的,而且我还需要参数。第二种方法不适用于调用,因为字符串不是 IAlertSource

标签: c# .net generics ambiguous-call


【解决方案1】:

简单地说:where 限制在确定要使用哪个方法重载时不使用。因此,当您忽略该信息时,使用哪个重载就变得不明显了。您可能会争辩说精确马赫更好,但事实并非如此。如果您忽略此信息,则可以使用字符串作为参数调用这两种方法。

【讨论】:

  • Eric Lippert 的相关文章:Constraints are not part of the signature
  • 但是为什么,如果我去掉可选参数,它会正确解析?
  • @AlessandroD'Andria 它不是关于可选参数,而是关于泛型类型参数,这就是他们决定实现它的方式。就像有人认为它不值得付出努力和复杂一样简单。
  • @Rafal 也许我丢失了一些东西,但是如果你从这两种方法中删除可选参数,它会解析为正确的重载。
  • @AlessandroD'Andria 实际上你对可选参数是正确的(对我来说小惊喜:))。然而我的回答是,我只是他们的做法而已。
猜你喜欢
  • 2018-11-26
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2015-08-28
相关资源
最近更新 更多