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) {
...
}