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?

    • 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.

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

      Oops. You beat me to it. Thank you!

      (note from Mak โ€“ combined these two comments)

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

    • Hey Joe,

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

  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.

    • 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.