How to remove ambiguous method call in c#

Here I have a simple scenario with two methods where I get an ambiguous invocation from one another:

This is a my code:

public IEnumerable<JobsViewModel> GetJobsViewModels(Guid vesselId, int status, Func<JobsNoSubsYpdcResult, bool> predicate = null)
    => predicate == null
        ? Mapper.Map<IEnumerable<JobsViewModel>>(_procedureService.Tech_GetJobsNoSubsYPDC(vesselId, status))
        : Mapper.Map<IEnumerable<JobsViewModel>>(_procedureService.Tech_GetJobsNoSubsYPDC(vesselId, status).Where(predicate));

public IEnumerable<JobsViewModel> GetJobsViewModels(Guid vesselId, int status, Func<JobsViewModel, bool> predicate = null)
    => predicate == null
        ? GetJobsViewModels(vesselId, status)
        : GetJobsViewModels(vesselId, status).Where(predicate);

I dont like changing the names of methods but from the second one I get the error message:

Ambiguous Invocation

I would like to call first one from second one like I am trying to do, does anybody know how can I do this without changing the method names otherwise I am supposed to change them ?

Jon Skeet
people
quotationmark

The only way to do this would be to fill in the optional parameter with a value of the appropriate type, so that the compiler knows which overload to pick. For example:

public IEnumerable<JobsViewModel> GetJobsViewModels(
    Guid vesselId,
    int status,
    Func<JobsViewModel, bool> predicate = null)
{
    // We're never filtering by JobsNoSubsYpdcResult, but this
    // satisfies overload resolution
    Func<JobsNoSubsYpdcResult, bool> resultPredicate = null;
    return predicate == null
        ? GetJobsViewModels(vesselId, status, resultPredicate)
        : GetJobsViewModels(vesselId, status, resultPredicate).Where(predicate);
}

Or to avoid repetition:

public IEnumerable<JobsViewModel> GetJobsViewModels(
    Guid vesselId,
    int status,
    Func<JobsViewModel, bool> predicate = null)
{
    // We're never filtering by JobsNoSubsYpdcResult, but this
    // satisfies overload resolution
    Func<JobsNoSubsYpdcResult, bool> resultPredicate = null;
    var allResults = GetJobsViewModels(vesselId, status, resultPredicate);
    return predicate == null
        ? allResults : allResults.Where(predicate);
}

Or to avoid even more repetition, introduce your own extension method:

public static IEnumerable<T> OptionalWhere<T>(
    this IEnumerable<T> source,
    Func<T, bool> predicate) =>
    predicate == null ? source : source.Where(predicate);

Then you can rewrite both methods to use that:

public IEnumerable<JobsViewModel> GetJobsViewModels(Guid vesselId, int status, Func<JobsNoSubsYpdcResult, bool> predicate = null) =>
    Mapper.Map<IEnumerable<JobsViewModel>>(_procedureService.Tech_GetJobsNoSubsYPDC(vesselId, status))
        .OptionalWhere(predicate);

public IEnumerable<JobsViewModel> GetJobsViewModels(
    Guid vesselId,
    int status,
    Func<JobsViewModel, bool> predicate = null)
{
    // We're never filtering by JobsNoSubsYpdcResult, but this
    // satisfies overload resolution
    Func<JobsNoSubsYpdcResult, bool> resultPredicate = null;
    return GetJobsViewModels(vesselId, status, resultPredicate)
        .OptionalWhere(predicate);
}

(You can use an expression-bodied method if you're happy to cast null to Func<JobsNoSubsYpdcResult, bool> or use a static field for that.)

people

See more on this question at Stackoverflow