Gostaria de pegar todas as variantes de uma classe de exceção genérica e queria saber se existe uma maneira de fazer isso sem vários blocos de captura. Por exemplo, digamos que eu tenho uma classe de exceção:
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
e duas classes derivadas:
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
existe uma maneira de capturar ambos MyDerivedStringException
e MyDerivedIntException
em um bloco de captura.
Eu tentei isso:
try
{
...
}
catch(Exception e) when (e is MyDerivedStringException || e is MyDerivedIntException)
{
}
mas não é muito limpo e significa que não tenho acesso MyProperty
.
Estou interessado em uma solução geral para o problema, mas no meu caso, a exceção genérica é definida em uma biblioteca de terceiros que, conforme indicado abaixo, adiciona algumas restrições adicionais ao problema.
Exception
eMyException<T>
seria adequada.O teste se você
Type
é derivado de um genérico é:Mas isso é verdade apenas para os tipos derivados em si, como
MyException<int>
ouMyException<string>
.Se você tem mais derivativos, como
MyDerivedStringException
você teve que testar:Portanto, isso funciona para qualquer genérico existente, mas você precisa saber o nível de herança para este teste ou percorrer todos os tipos de base.
Então você pode fazer isso:
fonte
Essa implementação encaixa e desmarca se T: Value for Valuetype ... mas com relação à utilização, você pode controlar as implicações de desempenho com o número de vezes que tenta encaixar / desmarcar.
Lógica
fonte
Infelizmente, você não pode pegar com o
catch(MyException ex)
classe, pois espera um tipo.Sua melhor aposta seria criar uma classe ou interface base, capturá-la e obter o tipo a partir daí.
Já existe uma resposta aqui, sobre como obter o tipo e fazer isso.
fonte
essa implementação abstrai o delegado de manipulação para o tipo de exceção, longe do contexto do T / C ... Isso pode ser um pouco aventureiro, mas a parte interessante é que você pode injetar diferentes manipuladores, dependendo do escopo de reutilização e do contexto de T / C. utilização.
lógica de registro
fonte