C#代码中在编译期获取代码行号

本文介绍.NET 4.5之后引入的新特性:CallerMemberName、CallerFilePath 和 CallerLineNumber,这些特性允许开发者在不依赖.pdb文件的情况下获取当前执行代码的位置信息,包括文件路径、成员名称和行号。
部署运行你感兴趣的模型镜像

常规方式是使用

 new StackTrace(true).GetFrame(0).GetFileLineNumber(); 

等一系列操作。
这种操作有个问题是依赖 .pdb文件,在发布时我们一般会去除pdb文件。
如果这时候通过这种方式打印行数,会发现行号为0.

NET 4.5之后可以使用
CallerMemberName ,CallerFilePathCallerLineNumber 特性来在编译期获取相关信息
NET 4.5.3之后在方法内部可以使用使用 nameof 代替 CallerMemberName

private void WriteInfo(
    [CallerFilePath]string filePath = "", 
    [CallerMemberName]string memberName = "", 
    [CallerLineNumber]int lineNumber = 0)
{
    Trace.TraceInformation($"{filePath} {memberName} {lineNumber}");
}

在需要打印的地方以默认参数调用该函数即可

{
	// some code
	WriteInfo();
	// other code
}

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在处理用户关于在C#获取代码行的问题。根据引用内容,有三种方法: 1.引用[1]:使用StackTrace和StackFrame获取当前执行代码的行。 2.引用[2]:动态获取代码文件名,以及从异常堆栈中提取行(不推荐,因为字符串解析不可靠)。3.引用[3]:统计整个.cs文件的行数,这与获取当前执行代码的行不同。 用户的需求是获取代码执行点的行,因此引用[1]和引用[2]中的第一种方法(使用StackTrace)是相关的。 引用[1]提供了一个工具类CodeLineHelper,其中GetLineNo方法可以获取当前代码行。引用[2]则提供了获取文件名的方法,同时提到从异常中获取的方法(字符串解析,不推荐)。因此,我们将重点介绍使用StackTrace和StackFrame的方法。步骤:1.添加必要的命名空间:System.Diagnostics。2.创建一个方法,使用StackTrace(1,true)来跳过当前帧(因为当前方法是获取的方法,所以要跳过),然后获取第0帧(即调用该方法的那一帧)。3.从StackFrame中获取。 注意:获取需要编译时生成调试信息(PDB文件),在Release模式下可能无法获取(除非生成PDB)。我们将提供两个示例:-示例1:直接获取当前(在调用GetLineNo方法的地方)。 -示例2:在异常处理中获取(通过StackTrace获取异常发生点的行)。 同时,我们也要注意引用[2]中提到的从异常中获取的方法(字符串解析)并指出其不可靠性,因此不推荐。最后,生成相关问题。回答结构: 1.介绍使用StackTrace和StackFrame获取的方法。 2.提供示例代码。3.注意事项(需要PDB文件)。4.生成相关问题。</think>### C# 获取代码行的方法详解 在 C#获取当前执行代码的行,主要依靠 `System.Diagnostics` 命名空间中的 `StackTrace` 和 `StackFrame` 类。以下是三种实用方法: #### 方法一:获取当前(最常用) ```csharp using System.Diagnostics; public static int GetCurrentLineNumber() { // 参数1: 跳过当前方法帧(StackTrace本身) // 参数2: 需要文件信息 StackTrace st = new StackTrace(1, true); StackFrame frame = st.GetFrame(0); // 获取调用栈的当前帧 return frame.GetFileLineNumber(); // 返回行 } // 使用示例: void TestMethod() { int line = GetCurrentLineNumber(); Console.WriteLine($"当前: {line}"); // 输出调用处的行 } ``` [^1] #### 方法二:获取异常发生位置的行 ```csharp try { // 可能抛出异常的代码 } catch (Exception ex) { StackTrace trace = new StackTrace(ex, true); StackFrame frame = trace.GetFrame(0); int errorLine = frame.GetFileLineNumber(); Console.WriteLine($"异常发生在: {frame.GetFileName()} 第 {errorLine} 行"); } ``` [^2] #### 方法三:获取调用者行(通过 `CallerLineNumber` 特性) ```csharp using System.Runtime.CompilerServices; void LogMessage(string message, [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") { Console.WriteLine($"{file} 第 {line} 行: {message}"); } // 调用时自动注入行 LogMessage("发生错误"); // 自动填充调用处的行和文件名 ``` #### ⚠️ 注意事项 1. **PDB 文件要求**:行信息需要调试符文件(.pdb),在 Release 模式下需开启调试信息生成 ```xml <PropertyGroup> <DebugType>pdbonly</DebugType> </PropertyGroup> ``` 2. **性能影响**:频繁获取堆栈信息会影响性能,建议仅用于错误日志 3. **异步代码**:在 `async` 方法中可能获取到编译器生成的状态机行而非原始行 4. **行偏移**:多行语句可能返回语句起始行 > **最佳实践**:建议封装为日志工具类,结合异常信息和环境数据记录完整上下文[^1][^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值