不能用参数类型A调用类型A的方法

本文关键字:类型 方法 调用 不能 参数 | 更新日期: 2023-09-27 18:02:28

我不太明白。我试图创建一个MethodCallExpression,但我得到一个运行时错误,说明该方法不能与它所期望的类型调用?我对表达式树相当陌生,所以我确信我有一些落后的东西,但几乎每个我试图适应的例子都会导致这种情况。

using System;
using System.Linq;
using System.Linq.Expressions;
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            var helper = new Helper();
            var expr = helper.GetMatchExpr<TestClass>(t => t.Name, "foo");
        }
    }
    public class Helper
    {
        public Expression<Func<T, bool>> GetMatchExpr<T>(Expression<Func<T, object>> member, string searchValue)
        {
            var memberExpr = member.Body as MemberExpression;
            if (memberExpr == null)
                throw new ArgumentException("Expected member expression");
            var parameter = Expression.Parameter(typeof(T), "type");
            var property = Expression.Property(parameter, memberExpr.Member.Name);
            var propertyExpr = Expression.Convert(property, typeof(string));
            var matchMethod = typeof(Helper).GetMethod("IsMatch", new[] { typeof(object), typeof(string) });
            var valueExpr = Expression.Constant(searchValue, typeof(string));
            var matchExpr = Expression.Call(property, matchMethod, propertyExpr, valueExpr); // throws exception
            return Expression.Lambda<Func<T, bool>>(matchExpr, parameter);
        }
        public bool IsMatch(object input, string searchValue)
        {
            if (input == null)
                return true;
            var qWords = GetWords(searchValue);
            var pWords = GetWords(input.ToString());
            return (
                from qWord in qWords
                from pWord in pWords
                where qWord.Equals(pWord, StringComparison.OrdinalIgnoreCase)
                select qWord).Any();
        }
        public string[] GetWords(string input)
        {
            return string.IsNullOrEmpty(input)
                ? new string[0]
                : input.Split(' ');
        }
    }
    public class TestClass
    {
        public string Name { get; set; }
        public string Age { get; set; }
    }
}

例外是

附加信息:方法'Boolean IsMatch(System.Object)'按类型声明1 (ConsoleApplication4 ConsoleApplication4.Helper。TestClass]"不能使用系统类型的实例调用。对象'

回答一些问题:

作为练习,我试图构建这个类,以便您可以在对象T上指定将包含在搜索中的属性集合。因此,一旦设置了所有这些属性,您调用Apply(…),它将遍历成员表达式集合,获取它们的值,将其拆分为单个单词,对查询短语执行相同操作,然后返回具有与任何单词匹配的任何属性的任何对象。

我已经经历了大约5到6个不同的例子,看起来接近我想要达到的目标,这只是我目前的情况。

所以我想我不太明白"调用IsMatch对propertyexp "的结果。这是否意味着它在使用类似于result的结果。IsMatch或IsMatch(result)?如果是后者,难道任何东西都不能作为对象使用吗?

不能用参数类型A调用类型A的方法

看看你的方法调用表达式:

var matchExpr = Expression.Call(property, matchMethod, propertyExpr, valueExpr);

第一个参数是方法调用的目标-您试图调用IsMatch的对象。现在,在您的助手类中声明了IsMatch,因此您应该在该类的实例上调用它。例如:

var targetExpr = Expression.Constant(this, typeof(Helper));
var matchExpr = Expression.Call(targetExpr, matchMethod, propertyExpr, valueExpr);

这就删除了异常——但仍然不清楚这些代码是否会对您有所帮助。当表达式树可以转换为其他形式(例如SQL…)时,查询的表达式树表示通常很有用。但是没有LINQ提供程序会知道你的Helper.IsMatch方法做什么。

如果您的目标是在数据库中完成所有匹配工作,那么此解决方案将无法帮助您。如果您的目标只是完成匹配工作,那么您可以使用LINQ to Objects更简单地完成它,并且只需适当地调用方法并在需要时使用委托,而根本不使用IQueryable<T>