首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在C#中捕获表达式树

如何在C#中捕获表达式树
EN

Stack Overflow用户
提问于 2018-08-11 02:12:03
回答 2查看 218关注 0票数 1

我正在写一些调试/测试代码,我想在其中显示原始表达式并对任意表达式进行求值。

对于(琐碎的)示例:

代码语言:javascript
复制
IList<string> myString = /* Some string collection expression */

ShowMe(myString.Select(s => s.ToLower()));

在那里我实现了类似于ShowMe的东西:

代码语言:javascript
复制
public void ShowMe(/* Not sure what has to go here */)
{
    /* Not sure what has to go here */
    Console.WriteLine(expression.ToString();
    IEnumerable result = expression.Evaluate(); // or something
    foreach(item in result)
    {
        Console.WriteLine(/* etc. */)
    }
}

并将结果写入控制台,格式为:

myString.Select(s => s.ToLower())

(第一项)

(下一项

(等等...)

换句话说,我的ShowMe方法对表达式树而不是表达式的值进行操作,因此它既可以显示给定的表达式,也可以显示计算结果。

我不能简单地将ShowMe声明为:

代码语言:javascript
复制
public void ShowMe(Expression expr)

..。但是如果我声明的是

代码语言:javascript
复制
public void ShowMe(Expression<Func<Enumerable>> expr)

..。在某种程度上,我必须使用lambda表达式来调用我的方法,如下所示:

代码语言:javascript
复制
ShowMe(() => myString.Select(s => s.ToLower()))

..。但我不想这么做。

我相当确定这是可以做到的..。FluentAssertions做到了。例如:如果我执行下面这行测试代码:

代码语言:javascript
复制
(1 + 1).Should.Be(3)

我得到了以下结果:

要求(1 + 1)为% 3,但找到% 2。

FluentAssertion既计算了表达式(1+1),又捕获了表达式树,以便能够显示它计算的原始表达式。

我不知道这是怎么做到的,但我想做类似的事情。我该怎么做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-11 02:43:55

这本身对于任何方法都是不可能的。

所有这些库都只是解析堆栈跟踪并提取文件名和行号。然后,在给定行从源代码文件中提取表达式(虽然这包括一些解析/验证)。

同样值得注意的是,如果源代码不存在/不可用,则无法显示表达式。

票数 2
EN

Stack Overflow用户

发布于 2018-08-11 06:01:35

想出一个可以接受的折衷方案:

代码语言:javascript
复制
public static class ObjectHelper
{
    public static void ToConsole<T>(this IEnumerable<T> enumerable, Expression<Func<T,object>> expr)
        where T:class
    {
        var fn = expr.Compile();

        var result = enumerable.Select(s => fn(s));

        Console.WriteLine($"My data selected as {PrettyPrintExpression(expr)}");
        foreach(var element in result)
        {
            Console.WriteLine(/*  etc.  */);
        }
    }

    private static string PrettyPrintExpression(Expression<Func<T,object>> expr)
    {
        // Walk the expression tree to print as desired
    }
}

...which I可以像这样调用:

代码语言:javascript
复制
IList<MyObject> list = /* etc. */
list.ToConsole(s => new{/* any members I want out of MyObject */});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51791968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档