System.ArgumentNullException 在 Xname.Get 上创建调用表达式时

System.ArgumentNullException when creating a call expression on Xname.Get

我正在尝试使用表达式树在 XElement 源上创建动态查询。此查询的一部分需要比较 XElement 属性的值,并且在构建用于获取属性值的表达式时,我得到了 ArgumentNullException。它连接到 XName.Get 的 Expression.Call 但我不知道如何解释这种情况下的异常。

PS: 代码中的常量表达式只是为了这个例子。

代码:

var value = 
            Expression.Property(
                Expression.Call(Expression.Parameter(typeof(XElement), "attr1"), typeof(XElement).GetMethod("Attribute"), 
                    Expression.Call(typeof(XName).GetMethod("Get", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly), Expression.Constant("id"))), 
            "Value");

我只能猜测,因为如图所示的表达式树不可编译。

问题可能是因为您的 Expression.Parameter 电话。参数必须是等于传入的任何内容的引用。描述性名称 ("attr1") 仅用于调试目的。

如果这不能解决您的问题,请 post 完整的树(或至少更多)。

typeof(XName).GetMethod(
    "Get", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)

正如 PetSerAl 已经指出的,这是您的问题。但是删除 BindingFlags.Instance 不会解决任何问题,你需要指定你想要一个静态方法:

typeof(XName).GetMethod(
    "Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)

这仍然行不通,它抛出 AmbiguousMatchException,但我们越来越接近了。您的 Call 有一个 string 参数,因此我们需要指定我们想要 XName.Get:

的重载
typeof(XName).GetMethod("Get", new[] { typeof(string) })

(我们不需要指定BindingFlags,因为默认就可以了。)

通过此修改,您的代码段似乎工作正常。