Using the code at the end of this answer allows you to write code such as:
[HideFromStackTrace] // apply this to all methods you want omitted in stack traces
static void ThrowIfNull(object arg, string paramName)
{
if (arg == null) throw new ArgumentNullException(paramName);
}
static void Foo(object something)
{
ThrowIfNull(something, nameof(something));
…
}
static void Main()
{
try
{
Foo(null);
}
catch (Exception e)
{
Console.WriteLine(e.GetStackTraceWithoutHiddenMethods());
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
} // gets a stack trace string representation
// that excludes all marked methods
Here's one possible implementation:
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method, Inherited=false)]
public class HideFromStackTraceAttribute : Attribute { }
public static class MethodBaseExtensions
{
public static bool ShouldHideFromStackTrace(this MethodBase method)
{
return method.IsDefined(typeof(HideFromStackTraceAttribute), true);
}
}
public static class ExceptionExtensions
{
public static string GetStackTraceWithoutHiddenMethods(this Exception e)
{
return string.Concat(
new StackTrace(e, true)
.GetFrames()
.Where(frame => !frame.GetMethod().ShouldHideFromStackTrace())
.Select(frame => new StackTrace(frame).ToString())
.ToArray()); // ^^^^^^^^^^^^^^^ ^
} // required because you want the usual stack trace
} // formatting; StackFrame.ToString() formats differently
Note that this only causes marked methods to be excluded from one particular representation of the stack trace, not from the stack trace itself. I know of no way to achieve the latter.
P.S.: If all you want is to hide a method in the Call Stack window during a debugging session, simply apply the [DebuggerHidden]
attribute to the method.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…