Expression.Call causes "Static method requires null instance, non-static method requires non-null instance"

May*_*ron 7 c# lambda

I have viewed similar SO questions but cannot figure out why mine won't work. I need to convert my Func<string, bool> value to an Expression to be used in the Moq framework but I cannot get passed an error when trying to convert the Func to an Expression.

This is the error:

Static method requires null instance, non-static method requires non-null instance.

This is my sample code:

using System;
using System.Linq.Expressions;

namespace ConsoleApp1
{
    class Program
    {
        public class MyObject
        {
            public void Add<T>(Func<T, bool> value)
            {
                // Line below causes error: Static method requires null instance, 
                // non-static method requires non-null instance.
                Expression<Func<T, bool>> expression =
                    Expression.Lambda<Func<T, bool>>(Expression.Call(value.Method));


                // I need to use the expression for the line below that is commented out
                // (for context reasons I have included this)
                //_myMock.Setup(m => m.MyMethod(key, It.Is(expression))).Returns("test");
            }
        }

        public static void Main(string[] args)
        {
            // Call it using:
            var myObject = new MyObject();
            myObject.Add(new Func<string, bool>(x => x.StartsWith("test")));
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

Not sure if my function is a static or non-static, but I would have thought it was static. I inspected the Func object using the debugger and there is a field called "IsStatic" set to false (value.Method.IsStatic). A bit confused what else to try.

Thank you.

Stack Trace:

System.ArgumentException
  HResult=0x80070057
  Message=Static method requires null instance, non-static method requires non-null instance.
Parameter name: method
  Source=System.Core
  StackTrace:
   at System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression[] arguments)
   at ConsoleApp1.Program.MyObject.Add[T](Func`2 value) in C:\Users\userName\source\repos\ConsoleApp1\ConsoleApp1\Program.cs:line 14
   at ConsoleApp1.Program.Main(String[] args) in C:\Users\userName\source\repos\ConsoleApp1\ConsoleApp1\Program.cs:line 28

Run Code Online (Sandbox Code Playgroud)

Raf*_*fal 2

您在表达式调用中包装的方法不是静态的。

在此输入图像描述

要调用非静态方法,您需要有效的实例作为 t​​his 传递,如果您实际上使用 func 外部的某个变量,这可能会变得很棘手。您可以进一步检查该方法并查看其声明类型。需要它的实例才能使 Expression.Call 工作。


要进行模拟设置,因为这是您的目标,您可以修改您的Add方法并直接获取表达式

Add<T>(Expression<Func<T, bool>> expression)
{
    _myMock.Setup(m => m.MyMethod(key, It.Is(expression))).Returns("test");
}
Run Code Online (Sandbox Code Playgroud)

当像这样调用时,这就会起作用:

myObject.Add((string x) => x.StartsWith("test"));
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述