如何返回C#方法调用的语法上下文

莫斌

如果你写类似

this.MyMethod(this.MyMethod(myParam)).Should().BeNull();

使用FluentAssertions库,断言失败时会引发异常,并显示消息

Expected this.MyMethod(this.MyMethod(myParam)) to be <null>, but found "foo".

为了产生这样有意义的异常消息,它如何设法获取方法调用的语法上下文?显然,使用了某种类型的反射,并且可能进行了一些堆栈跟踪检查(实际上,它仅在Debug模式下并且当表达式以单行编写时才可以正常工作),但是究竟如何呢?

更具体地说,如何使用签名编写方法

public static string GetSyntacticContext(object parameter);

满足以下条件(在“调试”模式下)?

GetSyntacticContext("foo")
    .Should().Be("\"foo\"");

GetSyntacticContext(myParam + 1)
    .Should().Be("myParam + 1");

GetSyntacticContext(this.MyMethod(this.MyMethod(myParam)))
    .Should().Be("this.MyMethod(this.MyMethod(myParam))");
Timwi

您提到它仅在Debug模式下有效,并且仅当表达式写在一行中时才起作用。实际上,“调试”模式下的异常堆栈跟踪包含源文件的完整路径以及通往异常发生位置的每个堆栈帧的行号。

因此,库可以从文件中读取该行并进行检查。它可能会对该行进行完整的表达式解析,但更有可能他们选择了使用正则表达式的快捷方式。在您引用的所有示例中,它真正需要做的就是删除.Should()及其后的所有内容。

在您的位置,我将稍微修改源文件(例如,更改间距和/或在行中间添加一些/ *注释* /),以查看异常消息是否保留了这些文件。如果是这样,我们知道它是从源文件读取的。如果没有,我敢打赌,它仍然从源文件中读取,但是对相关行执行语法分析并对其进行重构。

您的假设GetSyntacticContext方法可能会执行类似的操作:使用文件名/行号信息获取当前堆栈帧,然后从文件中读取该行。像这样:

public static string GetSyntacticContext(object parameter)
{
    var st = new StackTrace(fNeedFileInfo: true);
    var frame = st.GetFrame(1);
    return File.ReadLines(frame.GetFileName()).Skip(frame.GetFileLineNumber() - 1).FirstOrDefault();
}

请注意,此示例未使用任何parameter参数。在此示例中,我没有尝试检测GetSyntacticContext对方法调用语法的调用并提取其中的代码;它只返回整个代码行,缩进和全部。

顺便说StackFrame一句,该类型也有一个GetMethod()方法,因此您可以获取对该方法的运行时引用,该引用包含对的相关调用GetSyntacticContext不确定该怎么做,但是可以获取IL代码,和/或分析EXE文件附带的PDB文件的内容。但是,这实际上并不能为您提供实际的C#源代码。PDB文件充其量只能包含您已经拥有的相同文件名/行号信息,并且仍然不允许您区分同一条GetSyntacticContext语句中发生的多个调用

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用验证和可选请求上下文直接从C#代码调用Servicestack服务

如果调用方法然后对结果执行.Where(),如何执行“从上下文中的tbl返回(从上下文中的[表名]选择tbl]”)?

如何更改`this`上下文调用Vue实例方法?

如何调用具有参数“上下文”的方法

从当前Java上下文调用方法

C# 上下文错误

如何在数据库上下文中运行没有C#返回值的存储过程?

我如何知道异步方法调用是否更改了调用者的上下文?

查找更复杂语言的上下文无关语法的方法

如何获取C ++异常的上下文?

如何解析上下文相关语法?

如何获得该语言的上下文无关语法?

什么是C#“逻辑调用上下文”的Java等效项

返回变量在上下文C#中不存在

spring boot如何为调度任务设置安全上下文以调用安全方法?

当您在其他类中调用方法时,如何获取上下文?

XCTestExpectation:如何避免在等待上下文结束后调用执行方法?

如何在“上下文”和“ it”块内部和外部调用相同的方法

静态方法如何从调用活动中获取上下文?

如何在调用位置而不是定义位置的上下文中执行方法?

如何在超级方法(创建)调用中传递上下文(odoo 12)

SpelEvaluationException:尝试调用空上下文对象上的方法

从静态上下文调用非静态方法

Android - 从 onReceive 中调用的方法获取上下文?

静态上下文中的Java方法调用链接

从静态上下文中的 a 调用非静态方法

从非静态上下文中调用静态方法

在Thymeleaf中禁用静态上下文和方法调用

JavaScript调用方法没有相同的上下文