【问题标题】:Get expression arguments?获取表达式参数?
【发布时间】:2016-11-03 15:10:59
【问题描述】:

好的,问题来了:

int a = 111;
int b = 222;

Expression<Func<int>> expr = ()=> someClass.SomeWork(a) + b + 1;

如您所见,有 3 个不同的参数:someClass、a、b。它们都来自另一个执行范围,但不是。我怎样才能得到它们?我的意思是,一般来说,我只想要外部范围的变量。

例如,我想这样使用它:

var result = InvokeAndLog(expr);//this will invoke expression and print out everything I need from these arguments.

【问题讨论】:

  • 您必须先编译表达式,然后才能使用expr.Compile() 使用它。现在您可以像使用任何其他委托一样简单地调用返回的Func
  • 我认为问题不是关于如何编译和执行这个表达式。
  • 如果你想解析表达式找到引用的变量,看看这个,它可能会给一些提示stackoverflow.com/questions/7220626/…

标签: c#


【解决方案1】:

好的,伙计们,我自己找到了答案。这里是:

internal class Program
{
    public static int Method1()
    {
        return new Random(0).Next(10000);
    }

    public class MyClass
    {
        private int var = 11111;

        public int GetSome(int val)
        {
            return var * val;
        }
    }

    private static void Main()
    {

        var clas = new MyClass();
        int a = 111;
        int b = 222;
        Expression<Func<int>> expr = () => a * 2 - clas.GetSome(b) + b + 1 - Method1();
        var result = InvokeAndLog(expr);
    }

    private static T InvokeAndLog<T>(Expression<Func<T>> expr)
    {
        var visitor = new ArgumentsVisitor();
        visitor.Visit(expr);
        Console.WriteLine("Inputs: {0}", string.Join(", ", visitor.Arguments));
        return expr.Compile()();
    }
}

这里的主要类是 ExpressionVisitor 的后代。我只是覆盖了它的成员访问者并将所有成员聚合到一个集合中:

    public class ArgumentsVisitor : ExpressionVisitor
    {
        private readonly HashSet<MemberInfo> _all = new HashSet<MemberInfo>();

        public IEnumerable<MemberInfo> Arguments
        {
            get { return _all; }
        }

        protected override Expression VisitMember(MemberExpression node)
        {
            _all.Add(node.Member);
            return base.VisitMember(node);
        }
    }

然后我将visitor应用于表达式并打印出所有变量!谢谢,微软 =)

【讨论】:

  • 好的,我得到了你想要的,但我看不出有任何理由不提供你的代表真正需要的参数,但要依赖外部定义委托的范围,这对我来说似乎是一个糟糕的设计,因此您需要那些肮脏的黑客来获取属性。
  • 我根本不想使用它们。但这是现实世界,存在遗留问题。要查看没有重复会发生什么 - 您需要对 1000 个函数进行一些检查。如果所有东西都是在没有 hack 的情况下构建的,那么一开始就不需要 hack。
  • 这对我来说似乎是在问题中获得良好答案所需的非常重要的信息,显然不清楚的问题会导致无帮助的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2022-09-27
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多