7

I'm having some troubles to check the proper type on a switch statement. I have these classes that extends from Exception

public abstract class DomainException<T>: Exception { public readonly DomainExceptionCodes Code; public readonly T Metadata; public DomainException(DomainExceptionCodes code, T metadata): base(message: code.GetEnumDescription()) { Code = code; Metadata = metadata; } } public class EmptyFieldsException : DomainException<EmptyFieldsMetadata> { public EmptyFieldsException(EmptyFieldsMetadata metadata) : base(code: DomainExceptionCodes.EmptyField, metadata) { } } 

Let's asume there is a bunch of derived classes. What I need to do, is to be able to manage all of the derived clases in the same way when handling the exception.

Something like:

try{ // code that raise the exception } catch (Exception e) { // some code here switch(e) { case DomainException: // do something break; default: //other code here break; } } 

However, because DomainException requires at least one argument for the generic type it's raising an error

enter image description here

I tried with object and dynamic, but then the type does not match

enter image description here

Any clues?

1
  • It's the same problem catch (DomainException e) will require an argument for the generic type, and dynamic and object won't match. I don't want to have a catch or a case for every derived class. I want to use the base class Commented Sep 6, 2022 at 6:17

2 Answers 2

8

Unfortunately for your problem, that's not how generics work in .NET. The generic type argument is not erased, so A<T> is not A<object> (which would of course violate type safety!).

If you can change the definition of DomainException<T>, the best solution would be to add an intermediate non-generic type:

class DomainException: Exception { public readonly DomainExceptionCodes Code; } class DomainException<T>: DomainException { public T Metadata; } 

Then you can just catch the non-generic exception to get the code, and only need the generic variant to access the metadata (which presumably means you already know what type to expect there).

If you can't change the exception definition, unfortunately your only recourse is to use reflection. Something like this should work:

try { ... } catch (Exception ex) when ( ex.GetType().IsGenericType && ex.GetType().GetGenericTypeDefinition() == typeof(DomainException<>) ) { ... } 

Unfortunately, in this case even to access the code, you'll need to use reflection.

Sign up to request clarification or add additional context in comments.

Comments

1

as mentioned by this SO question, you can't rally catch all types at once. The code below (taken from the other question) should do what you need.

// ... catch (FaultException ex) { Type exceptionType = ex.GetType(); if (exceptionType.IsGenericType) { // Find the type of the generic parameter Type genericType = ex.GetType().GetGenericArguments().FirstOrDefault(); if (genericType != null) { // TODO: Handle the generic type. } } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.