debugging C#库方法[Conditional(“RELEASE”)]仍在编译器中调用

7xzttuei  于 8个月前  发布在  C#
关注(0)|答案(1)|浏览(112)

MyLib.dll中有以下代码:

[Obsolete("This method is for debugging only. Remove all calls to this method once done.")]
    public void SetLaunchCount(int count)
    {
        ThrowOnReleaseBuild();
        launchEntry.Set(count);
    }

    [Conditional("RELEASE")]
    static void ThrowOnReleaseBuild()
    {
        throw new InvalidOperationException("This method must not be called outside of DEBUG build"); ;
    }

当我在同一个解决方案中使用一个项目(在我的情况下是MAUI)测试它时,它工作得很好。然而,当打包并上传到Nuget(通过我们的私人Github Nuget提要)时,调用SetLaunchCount总是抛出,堆栈跟踪显示调用ThrowOnReleaseBuild
我已经仔细检查过了,编译版本确实有DEBUG符号(更准确地说,没有RELEASE符号):

我还尝试添加另一个Debug.WriteLine方法来确认它:

为什么它不起作用?例如,我检查了Debug.WriteLine的(反编译)源代码,它的编码就像我的方法一样:

[Conditional("DEBUG")]
        public static void WriteLine(string? message) =>
            s_provider.WriteLine(message);

编辑:添加更多信息:

  • 该库是在Release Profile中构建的。
  • 请参阅this answer关于我以前使用Conditional的问题。不知何故,它现在不工作。
fd3cxomn

fd3cxomn1#

它按预期工作。从documentation可以读到(强调我的),
将ConditionalAttribute应用于方法向编译器表明,除非定义了与ConditionalAttribute关联的条件编译符号,否则不应将对该方法的调用编译为Microsoft中间语言(MSIL)。
因此,当你使用Debug.WriteLine并使用RELEASE或DEBUG标志编译代码时,并不是Debug.WriteLine中的代码被删除了,而是调用本身不存在了--这就是为什么“它能工作”。
在DEBUG模式下,SetLaunchCount方法受到以下影响:

[Obsolete("This method is for debugging only. Remove all calls to this method once done.")]
public void SetLaunchCount(int count)
{
    ThrowOnReleaseBuild(); <-- this is removed in DEBUG, and not in RELEASE
    launchEntry.Set(count);
}

当你在Release模式下将其打包到NuGet中时,方法就在那里,如果你在DEBUG或RELEASE中编译代码,不会影响它,因为它不是你的代码调用标记为Conditional属性的方法。你只调用SetLaunchCount
如果你将方法ThrowOnReleaseBuild公开并从代码中调用它,即使它在Nuget中-它也会像你期望的那样工作,因为对该方法的调用取决于条件。

相关问题