When you want to exclude a method from showing up in the stack trace, you can apply the StackTraceHidden attribute to the method:
[System.Diagnostics.StackTraceHidden]
public static void Throw()
{
//check conditions and throw
}
Code language: C# (cs)
Note: This attribute was added in .NET 6.
You can apply StackTraceHidden to a class to hide all of its methods from the stack trace:
[System.Diagnostics.StackTraceHidden]
public static class Helpers
{
//lots of exception thrower helper methods
}
Code language: C# (cs)
Use StackTraceHidden with throw helper methods
StackTraceHidden is very useful for hiding throw helper methods. Devs often use these methods to get rid of redundant if-then-throw statements. The problem is these methods pollute the stack trace. Here’s an example of what the stack trace looks like when you call ArgumentNullException.ThrowIfNull():
System.ArgumentNullException: Value cannot be null. (Parameter 'employee.FirstName')
at System.ArgumentNullException.Throw(String paramName)
at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
at Program.Process(Employee employee) in D:\Program.cs:line 19
Code language: plaintext (plaintext)
You can use the StackTraceHidden attribute to eliminate the throw helper methods from the stack trace. Here’s an example of writing a method that’s equivalent to ArgumentNullException.ThrowIfNull() except it’s hidden from the stack trace:
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
[System.Diagnostics.StackTraceHidden]
public static class Helpers
{
public static void ThrowIfNull([NotNull] object? argument,
[CallerArgumentExpression("argument")] string paramName = null)
{
if (argument == null)
{
throw new ArgumentNullException(paramName);
}
}
}
Code language: C# (cs)
Note: It’s also using the CallerArgumentExpression attribute to automatically get the argument names.
Here’s the stack trace now. Notice it doesn’t have the Helpers.ThrowIfNull() call in it:
System.ArgumentNullException: Value cannot be null. (Parameter 'employee.FirstName')
at Program.Process(Employee employee) in D:\Program.cs:line 19
Code language: plaintext (plaintext)
Comments are closed.