对集合应用动态生成的表达式会引发异常

本文关键字:表达式 异常 集合 应用 动态 | 更新日期: 2023-09-27 18:00:05

我有以下类:

public class Order
{
    public string Code { get; set; } 
}

我有一个顺序列表,表达式类型的List<Order>,当我应用这样的过滤器时:

var buildExpressionFilter = ExpressionQuery
            .Empty
            .WithType(typeof(Order)) 
            .AndContains("Code", "af")
            .GetResult();
Expression<Func<Order, bool>> normalFilter = x => x.Code.Contains("af");
var orders = GetOrders();
var result = orders.WhereByFilter(buildExpressionFilter).ToList(); //fails as shown below
var result2 = orders.WhereByFilter(normalFilter ).ToList(); //works ok

buildExpressionFilter具有以下属性:

正文:{x=>(True AndAlso x.Code.Contains("'af'"))}

调试视图:。Lambda#Lambda1(Artemis.Sample.Order$x){真&amp。调用($x.Code)。包含("'af'")}

并使用一种扩展方法,看起来像:

public static IEnumerable<T> WhereByFilter<T>(this IEnumerable<T> collection, Expression filter)
        {
            dynamic dynamicFilter = filter;
            dynamic function = dynamicFilter.Compile();
            dynamic result = Enumerable.Where(collection, function); //CRASHES HERE
            return result;
        }

我得到以下错误:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException : An unexpected exception occurred while binding a dynamic operation
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, ref DynamicMetaObject deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
   at Microsoft.CSharp.RuntimeBinder.CSharpInvokeBinder.FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
   at System.Dynamic.InvokeBinder.FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args)
   at System.Dynamic.DynamicMetaObject.BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
   at System.Dynamic.InvokeBinder.Bind(DynamicMetaObject target, DynamicMetaObject[] args)
   at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
   at System.Runtime.CompilerServices.CallSiteBinder.BindCore(CallSite`1 site, Object[] args)
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2<T0,T1>(CallSite site, T0 arg0, T1 arg1)
   at Artemis.Common.Collection.CollectionExtensions.WhereByFilter(IEnumerable`1 collection, Expression filter) in CollectionUtils.cs: line 25

很明显,buildExpressionFilter没有正确构造,因为使用常规过滤器进行调用是有效的。

有人知道如何解决这个问题吗?我的buildExpressionFilter可能出了什么问题?

对集合应用动态生成的表达式会引发异常

我把你发布的确切代码放在你的问题和GitHub链接中。在我的示例中,代码运行良好(尽管它不处理Order.Codenull值)。我尝试了框架版本4.04.54.5.1.4.5.2,它们都运行良好。

我相信你已经对GitHub页面中发布的代码进行了修改,这导致了这个错误。这意味着我没有办法重现你的问题。

我认为您不需要在WhereByFilter实现中使用动态调用。这是因为您在编译时似乎知道T,在这种情况下,没有理由破坏类型安全性。这可能会澄清你得到的错误:

public static IEnumerable<T> WhereByFilter<T>(this IEnumerable<T> collection, Expression<Func<T, bool>>  filter)
{
    var function = filter.Compile();
    return collection.Where(function);
}