How to catch all variants of a generic exception in C#

Make MyException<T> implement an interface and check for an exception by the interface type.

Interface:

public interface IMyException
{
    string MyProperty { get; }
}

Generic class implementing the interface:

public class MyException<T> : Exception, IMyException
{
    public string MyProperty { get; }

    public MyException(T prop)
    {
        MyProperty = prop?.ToString();
    }
}

Derived classes:

public class MyDerivedStringException : MyException<string>
{
    public MyDerivedStringException(string prop) : base(prop)
    {

    }
}

public class MyDerivedIntException : MyException<int>
{
    public MyDerivedIntException(int prop) : base(prop)
    {

    }
}

Usage:

try
{
    // ...
}
catch (Exception e) when (e is IMyException)
{
    // ...
}

The same can be done by creating a base class that inherits from Exception and than making MyException<T> derive from that base class.


The test if your Type is derived from a generic is:

Type = typeof(something);
t.GetGenericTypeDefinition()==typeof(MyException<>);

But this is true only for derived types itself, like MyException<int> or MyException<string>.

If you have further derivatives like MyDerivedStringException you had to test on:

ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>);

So this works for any existing generic, but you need to know the level of inheritance for this test, or loop through all the base types.

So you could do this:

catch(Exception ex) when (ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>))

This implementation boxes and unboxes if T:Value is Valuetype... but with respect to utilization you can control performance implications with the number of times you attempt to box/unbox.

public class MyException<T> : MyException
{
    public T Prop => (T)base.Prop;

    public MyException(T prop) : base(prop)
    {

    }
}

public class MyException : Exception
{
    protected object Prop { get; }

    public MyException(object prop)
    {
         Prop = prop;
    }
}

Logic

try {
     ...
} catch(MyException e) {
    ...
}