C# 如何消除c语言中不明确的方法调用#
这里我有一个简单的场景,其中有两个方法,我从另一个方法得到一个不明确的调用: 这是我的代码:C# 如何消除c语言中不明确的方法调用#,c#,overloading,C#,Overloading,这里我有一个简单的场景,其中有两个方法,我从另一个方法得到一个不明确的调用: 这是我的代码: public IEnumerable<JobsViewModel> GetJobsViewModels(Guid vesselId, int status, Func<JobsNoSubsYpdcResult, bool> predicate = null) => predicate == null ? Mapper.Map<IEnumerab
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);
公共IEnumerable GetJobsViewModels(Guid vesselId,int状态,Func谓词=null)
=>谓词==null
? Mapper.Map(_procedureService.Tech_GetJobsNoSubsYPDC(vesselId,status))
:Mapper.Map(_procedureService.Tech_GetJobsNoSubsYPDC(vesselId,status).Where(谓词));
public IEnumerable GetJobsViewModels(Guid vesselId,int状态,Func谓词=null)
=>谓词==null
? GetJobsViewModels(容器ID、状态)
:GetJobsViewModels(vesselId,status).Where(谓词);
我不喜欢更改方法的名称,但从第二个方法中,我得到了错误消息:
模棱两可的调用
我想从第二个参数调用第一个参数,就像我正在尝试做的那样,有人知道我如何做到这一点而不更改方法名称,否则我应该更改它们吗?您需要提供可选参数,并向编译器说明其类型,即使值为
null
:
GetJobsViewModels(vesselId, status, (Func<JobsNoSubsYpdcResult, bool>)null)
GetJobsViewModels(vesselId,status,(Func)null)
编辑:在OP提出的特定情况下,最好是
另一方面,此答案中所示的解决方案可以普遍应用,也可以在消除重载歧义时应用,其中另一个重载没有可设置为非可选的可选参数(例如,在调用某些构造函数时).唯一的方法是用适当类型的值填充可选参数,以便编译器知道选择哪个重载。例如:
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);
}
public IEnumerable GetJobsViewModels(
Guid vesselId,
国际地位,
Func谓词=null)
{
//我们从不按JobsNoSubsYpdcResult筛选,但是
//满足过载分辨率
Func resultPredicate=null;
返回谓词==null
?获取作业视图模型(容器ID、状态、结果预测)
:GetJobsViewModels(vesselId、状态、结果预测)。其中(谓词);
}
或者为了避免重复:
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);
}
public IEnumerable GetJobsViewModels(
Guid vesselId,
国际地位,
Func谓词=null)
{
//我们从不按JobsNoSubsYpdcResult筛选,但是
//满足过载分辨率
Func resultPredicate=null;
var allResults=GetJobsViewModels(vesselId、status、resultPredicate);
返回谓词==null
?allResults:allResults.Where(谓词);
}
或者,为了避免更多重复,请介绍您自己的扩展方法:
public static IEnumerable<T> OptionalWhere<T>(
this IEnumerable<T> source,
Func<T, bool> predicate) =>
predicate == null ? source : source.Where(predicate);
公共静态IEnumerable选项where(
这是一个数不清的来源,
Func谓词)=>
谓词==null?source:source.Where(谓词);
然后您可以重写这两种方法以使用:
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);
}
public IEnumerable GetJobsViewModels(Guid vesselId,int status,Func predicate=null)=>
Mapper.Map(_procedureService.Tech_GetJobsNoSubsYPDC(vesselId,status))
.可选where(谓词);
公共IEnumerable GetJobsViewModels(
Guid vesselId,
国际地位,
Func谓词=null)
{
//我们从不按JobsNoSubsYpdcResult筛选,但是
//满足过载分辨率
Func resultPredicate=null;
返回GetJobsViewModels(vesselId、状态、结果预测)
.可选where(谓词);
}
(如果您愿意将
null
强制转换为Func
或使用静态字段,则可以使用表达式体方法。)如果您确实想要所需的内容,则需要传递适当的谓词参数,例如GetJobsViewModels(vesselId、status、new Func(x=>true))代码>处理此问题的最佳方法是不要有两个不明确的重载,这样您就不需要记住如何在调用它们的任何地方对其进行特殊处理
由于您的第二个重载调用了第一个重载,我认为最合理的操作原因是删除该委托的默认参数值:
public IEnumerable<JobsViewModel> GetJobsViewModels(Guid vesselId, int status, Func<JobsViewModel, bool> predicate)
=> predicate == null
? GetJobsViewModels(vesselId, status)
: GetJobsViewModels(vesselId, status).Where(predicate);
现在,说了这么多,我真的看不出第二种方法的意义,因为在外部,我可以简单地插入一个。Where(…)
过滤器。由于该方法不能巧妙地处理这个谓词,比如传递它并在较低的级别上执行,或者优化它获取数据的方式,因此这实际上只是语法上的糖分
然而,这只是我的观点,我承认我不知道这一切将如何使用。我真正的答案是第一部分,你真的应该避免声明模棱两可的方法
另请参见以下问题:
当Roslyn进入现场时,过载分辨率发生了变化,他们决定记录这一变化,并使其中断,而不是重新引入旧的“错误”。请显示给你的那个错误的电话。@LasseV.Karlsen:我想它已经存在了。第二个表达式的主体包含对所描述方法的调用。如果跳过可选参数,那么这两个方法是完全相同的,编译器应该如何知道?或者,您可以简单地删除重载的默认值,如果您对它进行ommit,则不希望它调用,很可能是第二个重载。换句话说,只有在您实际指定委托的情况下,才可以调用第二个重载。如果没有谓词,第二个重载只会转发到第一个重载-因此实际上没有必要在没有谓词的情况下调用第二个重载,因此它不需要默认值。“无论如何,我不太明白第二个方法的意义,因为在外部,我可以简单地使用。其中(…)
”-嗯,如果OP需要提供一个带有特定签名的方法来接受谓词(因为外部代码会通过委托像那样调用它),那么它可能有它的用途。我本来想这样做,但真正的问题在于两个模型的属性<代码>作业视图模型
public IEnumerable<JobsViewModel> GetJobsViewModels(Guid vesselId, int status, Func<JobsViewModel, bool> predicate)
=> GetJobsViewModels(vesselId, status).Where(predicate);