C# – Hide a method from the stack trace

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 19Code language: plaintext (plaintext)

8 thoughts on “C# – Hide a method from the stack trace”

  1. For methods like ThrowIfNull(employee), is there a way to tell the static analyzers that in subsequent statements, employee will not be null?

    Reply
    • Good question. So I’m assuming you’re referring to the Nullable feature and specifically warning CS8604 (‘x could be null’).

      To get rid of that warning in the calling code, update the null-checking method to use [NotNull]object? argument (instead of the non-nullable – object argument), like this:
      public static void ThrowIfNull([NotNull]object? argument, ….).

      This makes it so the analyzer knows that the object was null-checked and therefore won’t be null after this method is called.

      This is actually what the built-in ArgumentNullException.ThrowIfNull() has, and I totally missed it because I didn’t have the Nullable feature turned on at the time. I’ll go ahead and update the code example in the article with this change too.

      Reply
    • nm. I found the [System.Diagnostics.CodeAnalysis.NotNull] attribute

      Oops. You beat me to it. Thank you!

      (note from Mak – combined these two comments)

      Reply
  2. Hey Mak, Is this available in .net framework?
    I just add that attribute into my code(net472, VS2022), and it doesn’t work.

    Reply
    • Hey Joe,

      This attribute was added in .NET 6. So unfortunately, no, it’s not available in your .NET Framework version.

      Reply
  3. Trying to use this attribute in a project using c# 8. It is not part of System.Diagnostics and yields an error.
    Please help.

    Reply
    • Hi Chris,

      Unfortunately this attribute was added in .NET 6, so it’s not available in older versions. You could try to implement this behavior yourself. Let’s say you’re logging exceptions in a centralized method (like Logger.Error() or whatever). You could get the stack trace (ex.ToString()) and remove the 2nd and 3rd lines from the string. If that’s something you’d like to do and need further help, feel free to ask me by replying to this.

      Reply

Leave a Reply to Maclain Wiltzer Cancel reply