【问题标题】:CS, __LINE__ unavailability, can we write an alternative?CS,__LINE__ 不可用,我们可以写一个替代方案吗?
【发布时间】:2012-07-12 13:42:04
【问题描述】:

我是一名 Visual C++.net 程序员,大约一年前转换为 C#,我真的很想念 __FILE____LINE__。为了替换__FILE__,我写了一个很好的函数来返回class.method,这很棒,但是__LINE__没有合适的替代品(如果我错了,请纠正我!)。

我了解语言差异和技术限制、推理以及所有这些内容。

我要问的是:

编写一些 Visual Studio 扩展(我们所有的开发人员都会安装)是否可行,甚至可能,这将允许我们定义某种类型的令牌(~~LINE~~ 或其他东西),即当编译成可执行文件时,我们可以进行文本替换或将该符号切换为实际的 VS 行号?

我的扩展编程知识很少,我不知道分机。系统限制。

编辑澄清:

在 C++ 中,__FILE__ 在编译后将返回您编写代码的当前文件,以及__LINE__,您的当前行。这很重要,因为我们所有的日志记录系统(10 多年前)都需要一个 char* 用于文件,一个 int 用于我们正在记录的行。

C# 不能像 C++ 那样产生这两个“令牌”。

举个例子:

LoggingService.LogException(e, "file.cs", 1234);  

是我想要编译到我的可执行文件中的,并且

LoggingService.LogException(e, ~~MYFILE~~, ~~MYLINE~~); 

是我希望我的代码看起来的样子,并保存在磁盘上。我有一个合适的替代方法来获取文件,但我没有一个来获取文件。

编辑 2:

这些我们的版本构建,没有调试符号。为了适应这个修复,我们的产品安装量必须大几百兆,这是不可能的。

【问题讨论】:

  • 你在寻找一个 string.Replace Method() 吗?...如果你想用空行替换一行也看看 Environment.NewLine 方法我有点困惑你真正在问什么..
  • 有什么用?如果您想跟踪调用堆栈,运行时会为您执行此操作。
  • 为澄清而编辑。这是为了让我们的 C# 应用程序能够与我们的遗留错误日志服务(企业级应用程序)一起工作。
  • 此外,发布版本的调用堆栈信息非常差。
  • 我几乎可以肯定我已经为 _LINE_ 使用了一些替换类型的东西,但我不记得它是什么

标签: c# visual-c++ compilation c-preprocessor visual-studio-extensions


【解决方案1】:

来电者信息将在 .NET 4.5 中提供。这将被编译,比手动检查堆栈跟踪有了很大的改进:

http://msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx

public void LogException(Exception ex,
        [CallerFilePath] string filePath = "",
        [CallerLineNumber] int lineNumber = 0)
{
    // Log it!
}

感谢编译器的魔法,这将被称为:

LoggingService.LogException(e);

【讨论】:

  • 这看起来很有希望,我们目前是 4.0,但很快就会跳到 4.5。
  • 是的,就是这样——正如文档所说“调用者信息值在编译时作为文字发送到中间语言 (IL) 中。”所以调试无关紧要,也没有运行时损失——很好。
【解决方案2】:

您可以简单地先通过 C 预处理器运行所有 C# 代码,然后再编译结果。您需要更改 CS 文件的构建规则才能做到这一点。

【讨论】:

  • 既然可以使用堆栈帧,为什么还要这样做?
  • @Hogan,我不会,这只是回复原始问题。我怀疑 OP 想要它来记录异常,但也许还有其他原因(可能不是在编辑问题之后)。
  • Alexia,我认为这可能是一个很好的例子。当我们编译我们的项目时,我们可能会通过预处理器运行整个应用程序。 @Hogan,我没有调试符号,没有堆栈框架。
【解决方案3】:

注意:如果您正在处理异常,堆栈帧在异常中,因此不需要。我曾经用它来存储日志系统的行和文件信息,这是我能想到的唯一用例——但它“没那么快”。

警告:如果您的发行版本中没有符号,则某些信息将不可用。

using System;
using System.Diagnostics ;

StackTrace st=new StackTrace (0,true);

StackFrame sf=new StackFrame ();
sf=st.GetFrame (0);
Console.WriteLine ("FileName: {0}",sf.GetFileName ());
Console.WriteLine ("Line Number: {0}",sf.GetFileLineNumber ());
Console.WriteLine ("Function Name: {0}",sf.GetMethod ());

其中还有列和类型以及其他一些内容...查看此处了解更多信息。

http://msdn.microsoft.com/en-us/library/system.diagnostics.stackframe.aspx

【讨论】:

  • 不幸的是,我们没有符号。我们的应用程序在工厂上运行,安装大小至关重要。符号是不可能的。我确实使用这种方法进行调试构建!
【解决方案4】:

该行位于异常的堆栈跟踪中。但不是提取它,我认为你应该记录整个堆栈跟踪,因为它还有其他有用的调试信息(加上我相信由于预处理器语句,行号有时会偏离几行)

如果您在 Web 窗体或 MVC 中使用 ASP.Net Web 应用程序,我强烈推荐 ELMAH。它负责所有的日志记录

【讨论】:

  • 使用 Winforms。没有调试符号就没有堆栈跟踪,我们有发布版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 2021-04-27
  • 2021-08-25
  • 1970-01-01
相关资源
最近更新 更多