Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to perform a switch statement on a generic type in C#?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading