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
I tried with object
and dynamic
, but then the type does not match
Any clues?
CodePudding user response:
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.
CodePudding user response:
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.
}
}
}