从 LambdaExpression 获取对象实例

Get the object instance from a LambdaExpression

我想将 class 的实例传递给使用 Expression<T> 的方法并从方法中检索实例:

public class MyOb
{
    public void Receive(Expression<Func<Item>> item)
    {
        // Here I would like to get item as Item
        // Have tried various things such as
        var x = ((MemberExpression)(item.Body)).Member;
        
        int y = x.IntProp  // should be 123.
    }
}

public class Item
{
    public int IntProp { get; set; } = 123;
}

MyOb mo = new();
Item myItem = new();
mo.Receive(() => myItem);

这并不容易,因为编译器会生成一个特殊的 class 来处理闭包,闭包将存储局部变量 (myItem) 的值。这样的事情应该可以解决问题:

public static void Receive(Expression<Func<Item>> item)
{
    if (item.Body is MemberExpression { Expression: ConstantExpression constE })
    {
        var itemValue = constE.Type.GetFields()
            .Where(fi => fi.FieldType.IsAssignableTo(typeof(Item)))
            .Single() // possibly proper validation message if multiple found
            .GetValue(constE.Value);
        var intProp = ((Item)itemValue).IntProp; // your value
        Console.WriteLine(intProp); // will print 123 for your code
    }
}