I have the following code in 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"); ;
}
When I tested it using a project (MAUI in my case) in the same solution, it works fine. However, when packing it and uploading it to Nuget (through our private Github Nuget feed), calling SetLaunchCount
always throw and the stack trace shows call to ThrowOnReleaseBuild
.
I have double checked and the Debug build indeed has DEBUG
symbol (and more precisely, no RELEASE
symbol):
I also tried adding another Debug.WriteLine
method to confirm it:
Why is it not working? I checked the (decompiled) source code of Debug.WriteLine
for example, and it's coded just like my method:
[Conditional("DEBUG")]
public static void WriteLine(string? message) =>
s_provider.WriteLine(message);
EDIT: adding some more information:
The library was built in Release profile.
See this answer on my previous question about using Conditional
. Somehow it does not work now.
It works as expected. From the documentation you can read (emphasis mine) that
Applying ConditionalAttribute to a method indicates to compilers that a call to the method should not be compiled into Microsoft intermediate language (MSIL) unless the conditional compilation symbol that is associated with ConditionalAttribute is defined.
So when you use Debug.WriteLine
and you compile your code with RELEASE or DEBUG flag, it's not that the code inside the Debug.WriteLine
is removed. It's the call itself that's not there - that's why "it works".
So in your case:
In DEBUG mode the SetLaunchCount
method is affected in the following way:
[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);
}
When you pack this into NuGet in Release mode, the method is there and if you compile your code in DEBUG or RELEASE doesn't affect it as it's not your code that calls the method that is marked as Conditional
attribute. You only call SetLaunchCount
.
If you would make the method ThrowOnReleaseBuild
public and call it from your code, even if it would be in the Nuget - it would work as you expect as the call to that method would be there or not depending on the condition.