在调试构建中仍调用 [Conditional("RELEASE")] 的 C# 库方法

问题描述 投票:0回答:1

我在

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 feed)时,调用

SetLaunchCount
总是抛出异常,并且堆栈跟踪显示对
ThrowOnReleaseBuild
的调用。

我已经仔细检查过,调试版本确实有

DEBUG
符号(更准确地说,没有
RELEASE
符号):

我还尝试添加另一个

Debug.WriteLine
方法来确认它:

为什么不起作用?例如,我检查了

Debug.WriteLine
的(反编译的)源代码,它的编码就像我的方法一样:

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

编辑:添加更多信息:

  • 该库是在发布配置文件中构建的。

  • 请参阅我之前关于使用Conditional的问题的

    这个答案
    。不知怎的,现在不起作用了。

c# .net debugging compilation conditional-compilation
1个回答
0
投票

它按预期工作。从文档你可以读到(强调我的)

将 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);
}

当您在发布模式下将其打包到 NuGet 中时,该方法就在那里,如果您在 DEBUG 或 RELEASE 中编译代码,则不会影响它,因为不是您的代码调用标记为 
Conditional

属性的方法。您只需拨打

SetLaunchCount
如果您将方法 

ThrowOnReleaseBuild

公开并从代码中调用它,即使它位于 Nuget 中 - 它也会按照您的预期工作,因为对该方法的调用是否存在取决于条件。

    

© www.soinside.com 2019 - 2024. All rights reserved.