C# 使用动态 lambda 但在选择要使用的方法时得到不明确的匹配

C# Using dynamic lambda but getting an ambiguous match when selecting a method to use

根据 Pashov 的博客 post,我有以下用于 select 在过滤器选项之间切换的静态方法。

public static class ExpressionRetriever  
    {  
        private static MethodInfo containsMethod = typeof(string).GetMethod("Contains");  
        private static MethodInfo startsWithMethod = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });  
        private static MethodInfo endsWithMethod = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });



    public static Expression GetExpression<T>(ParameterExpression param, ExpressionFilter filter)  
    {  
        MemberExpression member = Expression.Property(param, filter.PropertyName);  
        ConstantExpression constant = Expression.Constant(filter.Value);  
        switch (filter.Comparison)  
        {  
            case Comparison.Equal:  
                return Expression.Equal(member, constant);  
            case Comparison.GreaterThan:  
                return Expression.GreaterThan(member, constant);  
            case Comparison.GreaterThanOrEqual:  
                return Expression.GreaterThanOrEqual(member, constant);  
            case Comparison.LessThan:  
                return Expression.LessThan(member, constant);  
            case Comparison.LessThanOrEqual:  
                return Expression.LessThanOrEqual(member, constant);  
            case Comparison.NotEqual:  
                return Expression.NotEqual(member, constant);  
            case Comparison.Contains:  
                return Expression.Call(member, containsMethod, constant);  
            case Comparison.StartsWith:  
                return Expression.Call(member, startsWithMethod, constant);  
            case Comparison.EndsWith:  
                return Expression.Call(member, endsWithMethod, constant);  
            default:  
                return null;  
        }  
    }  
}

一旦它到达行 return Expression.Call(member, startsWithMethod, constant); 就会抛出以下错误:

> System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'ExpressionRetriever' threw an exception.
  Source=JobsLedger.API
  StackTrace:
   at JobsLedger.API.ControllerServices.Shared.OrderAndFIlterHelpers.DynamicFilteringHelper.ExpressionRetriever.GetExpression[T](ParameterExpression param, ExpressionFilter filter) in C:\AURELIA.0 - JobsLedgerSPA -ASPNET CORE 3.0\JobsLedger.API\ControllerServices\Shared\OrderAndFIlterHelpers\DynamicFilteringHelper.cs:line 84
   at JobsLedger.API.ControllerServices.Shared.OrderAndFIlterHelpers.DynamicFilteringHelper.ConstructAndExpressionTree[T](List`1 filters) in C:\AURELIA.0 - JobsLedgerSPA -ASPNET CORE 3.0\JobsLedger.API\ControllerServices\Shared\OrderAndFIlterHelpers\DynamicFilteringHelper.cs:line 39
   at JobsLedger.API.ControllerServices.Shared.ODataFilterAndSort.ParginatedFilteredSorted[T](IQueryable`1 source, String query) in C:\AURELIA.0 - JobsLedgerSPA -ASPNET CORE 3.0\JobsLedger.API\ControllerServices\Shared\OrderAndFIlterHelpers\ODataFilterAndSort.cs:line 41
   at JobsLedger.API.ControllerServices.API.App.ClientServices.ClientServices.GetPaginatedClients(String query) in C:\AURELIA.0 - JobsLedgerSPA -ASPNET CORE 3.0\JobsLedger.API\ControllerServices\API\App\ClientServices\ClientServices.cs:line 65
   at JobsLedger.API.Controllers.API.App.ClientController.Index(String query) in C:\AURELIA.0 - JobsLedgerSPA -ASPNET CORE 3.0\JobsLedger.API\Controllers\API\App\ClientController.cs:line 28
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
> 
> Inner Exception 1: AmbiguousMatchException: Ambiguous match found.

如果我注释掉 private static MethodInfo containsMethodprivate static MethodInfo endsWithMethod 它现在可以工作了。

我发现这个 post's answer (same kind of problem) that said to use this 过载,但它已经这样做了。

我怎样才能避免这种情况,以便它可以 select 在不同的方法之间看到不明确的选择?

虽然您的问题没有具体说明,但从提供的堆栈跟踪中推断您是 运行 .NET Core 环境中的代码。

请注意,无法在 .NET Framework 环境中重现此错误。

在 .Net Core 中测试时,此行出现错误

private static MethodInfo containsMethod = typeof(string).GetMethod("Contains");  

请注意缺少用于缩小方法匹配范围的参数类型。

通过提供像

这样的参数类型
private static MethodInfo containsMethod = 
    typeof (string).GetMethod("Contains", new Type[]{typeof (string)});

错误已解决,代码按预期运行。

.Net Fiddle of working code