You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带[Conditional("RELEASE")]的类库方法在Debug构建中仍被调用问题

问题:Conditional特性在NuGet包中失效

我在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项目中测试时一切正常,但将类库打包上传至私有GitHub NuGet源后,调用SetLaunchCount始终抛出异常,堆栈跟踪显示调用了ThrowOnReleaseBuild方法。

我已确认Debug构建确实包含DEBUG符号(且无RELEASE符号),还通过添加Debug.WriteLine方法验证了这一点。查看Debug.WriteLine的反编译源码,其实现方式与我的方法一致,但代码无法正常工作。

补充信息:

  • 类库通过Release配置构建。
  • 此前关于Conditional的解决方案现已失效。

解决方案

核心原因

你用Release配置构建类库时,编译器会基于类库自身的构建符号(而非引用项目的符号)处理Conditional特性。也就是说,类库在Release模式下编译时,自身定义了RELEASE符号,所以ThrowOnReleaseBuild方法的调用会被保留在编译后的程序集中。当引用该NuGet包的项目以Debug模式运行时,调用这个方法就会触发异常——因为类库编译后的代码里已经包含了这个调用,不会因为引用项目的符号而移除。

修正方案

要实现“仅在引用项目的Release构建中触发检查”,可以采用以下两种方式:

  1. 反转Conditional特性的符号,重载方法
[Obsolete("This method is for debugging only. Remove all calls to this method once done.")]
public void SetLaunchCount(int count)
{
    ThrowIfNotDebugBuild();
    launchEntry.Set(count);
}

[Conditional("DEBUG")]
static void ThrowIfNotDebugBuild()
{
    // 空方法,仅在DEBUG构建中保留调用(无实际操作)
}

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

引用项目为Debug构建时,会调用空方法;为Release构建时,会调用抛出异常的版本,完全适配引用项目的构建模式。

  1. 直接使用编译指令控制代码
[Obsolete("This method is for debugging only. Remove all calls to this method once done.")]
public void SetLaunchCount(int count)
{
#if RELEASE
    throw new InvalidOperationException("This method must not be called outside of DEBUG build");
#endif
    launchEntry.Set(count);
}

这种方式让引用项目在编译时,根据自身的构建符号决定是否包含异常抛出代码,完全不受类库构建配置的影响。

为什么Debug.WriteLine能正常工作?

Debug.WriteLine所在的类库(如System.Diagnostics.Debug)是针对不同构建符号发布了适配版本,或是通过#if DEBUG编译指令而非Conditional特性实现逻辑,因此能自动适配引用项目的构建模式。

内容的提问来源于stack exchange,提问作者Luke Vo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:55:02