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 ?
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.)
See more on this question at Stackoverflow