Je voudrais attraper toutes les variantes d'une classe d'exception générique et je me demandais s'il y avait un moyen de le faire sans plusieurs blocs catch. Par exemple, disons que j'ai une classe d'exception:
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
et deux classes dérivées:
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
existe-t-il un moyen d'attraper les deux MyDerivedStringException
et MyDerivedIntException
dans un bloc de capture.
J'ai essayé ceci:
try
{
...
}
catch(Exception e) when (e is MyDerivedStringException || e is MyDerivedIntException)
{
}
mais ce n'est pas très propre et signifie que je n'y ai pas accès MyProperty
.
Je suis intéressé par une solution générale au problème, mais dans mon cas, l'exception générique est définie dans une bibliothèque tierce qui, comme indiqué ci-dessous, ajoute des contraintes supplémentaires au problème.
Exception
et ceMyException<T>
serait bien.Le test si votre
Type
est dérivé d'un générique est:Mais cela n'est vrai que pour les types dérivés eux-mêmes, comme
MyException<int>
ouMyException<string>
.Si vous avez d'autres dérivés comme
MyDerivedStringException
vous avez dû tester:Cela fonctionne donc pour tout générique existant, mais vous devez connaître le niveau d'héritage pour ce test, ou parcourir tous les types de base.
Vous pouvez donc faire ceci:
la source
Cette implémentation met en boîte et décompresse si T: Value est Valuetype ... mais en ce qui concerne l'utilisation, vous pouvez contrôler les implications en termes de performances avec le nombre de fois que vous tentez de décompresser / décompresser.
Logique
la source
Malheureusement, vous ne pouvez pas attraper avec le
catch(MyException ex)
classe, car il attend un type.Votre meilleur pari serait de créer une classe ou une interface de base, de l'attraper et d'obtenir le type à partir de là.
Il y a déjà une réponse, alors voici comment obtenir le type et le faire.
la source
cette implémentation résume le délégué de gestion pour le type d'exception loin du contexte du T / C ... Cela peut être un peu trop aventureux, mais la partie intéressante à ce sujet est que vous pouvez injecter différents gestionnaires en fonction de la portée de la réutilisation et du contexte de utilisation.
logique d'enregistrement
la source