Reputation: 850
Simplified, i have these 2 Extension
method:
public static class Extensions
{
public static string GetString(this Exception e)
{
return "Standard!!!";
}
public static string GetString(this TimeoutException e)
{
return "TimeOut!!!";
}
}
And here is where i use them:
try
{
throw new TimeoutException();
}
catch (Exception e)
{
Type t = e.GetType(); //At debugging this a TimeoutException
Console.WriteLine(e.GetString()); //Prints: Standard
}
I have more GetString()
extensions.
My try{...}catch{...}
is getting large and basically i search for ways to shorten it down to 1 catch that calls the extension based on the type of the exception.
Is there a way to call the right extension method at runtime?
Upvotes: 11
Views: 407
Reputation: 4091
Extension methods are the wrong tool here.
I would foster the use of polymorphism to solve your problem:
public abstract class BaseException : Exception
{
public abstract string GetString();
}
public sealed class TimeoutException : BaseException
{
public override string GetString() => "TimeOut!!!";
}
public sealed class MyException : BaseException
{
public override string GetString() => "Standard!!!";
}
Usage
try
{
throw new TimeoutException(); //or whatever BaseException's children
}
catch (BaseException e)
{
//here I'm assuming you know that you are swallowing the exception (which may be an anti-pattern)
Console.WriteLine(e.GetString());
}
It looks like you have not the full control over which and when exceptions are thrown. Another possibility would be to add 1 catch clause for each behavior (rather than for each exception type) and get rid of GetString()
:
try
{
throw new TimeoutException();
}
catch (Exception e) when (e is ArgumentNullException || e is FormatException)
{
//do something
}
catch (Exception e) when (e is TimeoutException)
{
//do something
}
catch (Exception e)
{
throw new NotImplementedException($"Hey Mike, write something for {e.GetType()}, will ya?"); //idea from Jeroen
}
Upvotes: -1
Reputation: 8868
As Yacoub Massad suggests you can use dynamic
, because with dynamic
method overload resolution is deferred at runtime through late binding.:
public static class Extensions
{
public static string GetString<T>(this T e) where T : Exception
{
// dynamic method overload resolution is deferred at runtime through late binding.
return GetStringCore((dynamic)e);
}
static string GetStringCore(Exception e)
{
return "Standard!!!";
}
static string GetStringCore(TimeoutException e)
{
return "TimeOut!!!";
}
static string GetStringCore(InvalidOperationException e)
{
return "Invalid!!!";
}
}
This should make the trick.
Upvotes: 4