Veuillez noter qu'il s'agit d'une amélioration par rapport aux réponses existantes.
Le
Accepted answer de cette question est vraiment maladroite, car
- Il détermine la méthode que nous avons besoin de se cacher de trace de la pile par son nom en utilisant la chaîne pure.
- La division de la trace de pile est basée sur la méthode
string.Split
.
- Il cache juste une méthode de
StackTrace
propriété, pas plus.
Mais elle l'emporte sur lui-même la propriété StackTrace
(que le comportement souhaité de la question)
Le
Most Upvoted Answer est vraiment plus propre parce
- il utilise un attribut au lieu de spécifier le nom de la méthode que un string.
- Il peut être utilisé pour masquer plusieurs méthodes de
StackTrace
.
mais il est vraiment compliqué et en ajoutant deux autres classes juste pour les méthodes d'extension. Et le point faible le plus important ne surcharge pas la propriété StackTrace
elle-même.
Après avoir lu les deux précédentes solutions, je pense que je suis arrivé à la façon la plus simple et la plus propre (qui combinent le meilleur des deux premiers réponse à cette question)
ici est l'infrastructure nécessaire.
[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());
}
}
}
et voici un exemple d'utilisation de l'infrastructure précédente
[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 Selon un commentaire par @Stakx sur cette réponse, qui est supprimé immédiatement après sa mise, il indique une idée importante:
Cette solution ne fonctionne que pour les exceptions personnalisées et sa solution fonctionne sur tous les types d'exceptions, ce qui est absolument correct.
D'après cela, voici une méthode d'extension, sans beaucoup plus complexe, qui pourrait résoudre le problème et fonctionner sur tous les types d'exception.
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());
}
}
qui est presque identique à son code, à l'exception intégrant la méthode IsDefined
.
Avez-vous regardé les aides de CollectionAssert? NUnit 2,4+; on dirait que vous êtes après AreEqual ou AreEquivalent. – alastairs
Ah merci - je suis nouveau à NUnit. Je suis toujours intéressé par la réponse à la première question si quelqu'un sait. – gordonmleigh
+1 parce que vous avez demandé une sorte de question folle, mais a expliqué pourquoi. Je ne peux pas vous dire combien ça me dérange de voir une question folle et je me demande pourquoi quelqu'un voudrait jamais ce qu'on lui demande. Bon travail! – Tony