首页 > 解决方案 > 从 .NET 库中,如何检查 RUNNING 程序集/应用程序是否处于调试版本中(未附加调试器)?

问题描述

我正在制作一个类库Foo(如果相关,则为 Xamarin Android 库,但如果可能,我更喜欢通用的 .NET 解决方案),我需要这样的东西:

if (builtInDebugConfig) 
{
    this.DoSomething();
}

现在Foo.dll调用上述代码时肯定会以Release模式编译。因此#if不可能肯定,Conditional也不应该工作(如果我错了,请纠正我,我也读过它是一个编译器属性)(问题的答案和我的测试确认Conditional有效)。我能想到的最接近的是Debugger.IsAttached,但是大多数时候我们在没有附加调试器的情况下测试应用程序。

有没有办法检测调用DEBUG程序集是否使用符号/配置编译?如果可能的话,我不希望调用(应用程序)代码在每个应用程序中都有这样的东西,因为它违背了目的:

#if DEBUG
    Foo.IsDebug = true;
#endif

更新:澄清我为什么要这样做:如果调用应用程序正在开发中并且不希望此类代码存在于最终视图中,我想启用调试代码(即启用 WebView 调试信号)。这就是为什么我对防止此类代码泄漏到 Release 构建的解决方案感兴趣的原因。

标签: c#.netxamarin.net-core

解决方案


您可以使用ConditionalinFoo来装饰方法 - 对该方法的任何调用都取决于调用代码是否定义了相关符号。所以像:

[Conditional("DEBUG")]
public void MaybeSetDebugMode()
{
    // Remember the decision
}

那么调用代码就可以无条件地编写代码调用了,而调用代码只有在编译调用代码时才被定义在if中MaybeSetDebugMode真正被编译。无论编译时定义的符号如何,DEBUG该方法Foo本身都会被编译。Foo.dll

这与 不同#if,后者在编译代码时确实取决于符号。

请注意,这就是Debug.WriteLineetc 的工作方式。

这样做的一个缺点:除非您采取更多行动,否则此代码绝对会存在于“最终构建”中。它必须,因为 Foo.dll 中代码的存在不能根据调用它的内容而改变。

因此,您实际上可能想要使用#if,例如:

#if FINAL_BUILD
public void MaybeSetDebugMode()
{
    // This method exists so that the calling code will still build
    // with the final DLL, but there won't be any "interesting" code
    // for anyone to find.
}

#else

public void MaybeSetDebugMode()
{
    // Interesting code goes here. This code won't be included in the final build,
    // but callers can call it unconditionally, because there'll be an empty
    // method in the final build.
}
#endif

推荐阅读