Обратите внимание, что это улучшение существующих ответов.
<Ч />
Принятый ответ на этот вопрос действительно неуклюж, поскольку
- Он определяет метод, который нам нужно скрыть от трассировки стека, по его имени, используя чистую строку.
- Разделение трассировки стека основано на методе
string.Split
.
- Он скрывает только один метод из свойства
StackTrace
, не более.
Но оно переопределяет StackTrace
само свойство (которое является желательным поведением вопроса)
<Ч />
Most Upvoted Answer действительно чище, потому что
- он использует атрибут вместо указания имени метода в виде строки.
- Может использоваться для сокрытия более одного метода от
StackTrace
.
но это действительно сложно и просто добавление еще двух классов
для методов расширения.
И самое главное слабое место в этом не перевешивает
само свойство StackTrace
.
<Ч />
Прочитав предыдущие два решения, я думаю, что нашел самый простой и самый чистый способ (который объединяет лучшее из двух лучших ответов на этот вопрос)
вот инфраструктура, которая нужна.
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class StackTraceHiddenAttribute : Attribute
{
}
public class SomeException : Exception
{
public override string StackTrace
{
get
{
return string.Concat(
new StackTrace(this, true)
.GetFrames()
.Where(frame => !frame.GetMethod().IsDefined(typeof(StackTraceHiddenAttribute), true))
.Select(frame => new StackTrace(frame).ToString())
.ToArray());
}
}
}
и вот пример использования предыдущей инфраструктуры
[StackTraceHidden] // apply this to all methods you want to be omitted in stack traces
static void Throw()
{
throw new SomeException();
}
static void Foo()
{
Throw();
}
static void Main()
{
try
{
Foo();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
EDIT
Согласно комментарию @Stakx к этому ответу, , который удаляется сразу после ввода , он указывает на одну важную идею:
Это решение работает только для пользовательских определенных исключений, а его решение работает со всеми типами исключений, что абсолютно правильно.
В соответствии с этим, вот один метод расширения, без гораздо более сложного, который мог бы решить проблему и работать со всеми типами исключений.
public static class ExceptionExtensions
{
public static string GetStackTraceWithoutHiddenMethods(this Exception e)
{
return string.Concat(
new StackTrace(e, true)
.GetFrames()
.Where(frame => !frame.GetMethod().IsDefined(typeof(StackTraceHiddenAttribute), true))
.Select(frame => new StackTrace(frame).ToString())
.ToArray());
}
}
, который почти идентичен его коду, за исключением интеграции метода IsDefined
.