我在
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
的问题的
这个答案。不知怎的,现在不起作用了。
它按预期工作。从文档你可以读到(强调我的)
将 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 中 - 它也会按照您的预期工作,因为对该方法的调用是否存在取决于条件。