Вы не показали полный контекст вашего класса, который реализует ISaberpsicologiaExceptionHandler<T>
.Но только из определения этого интерфейса я бы сказал, что он не должен быть универсальным интерфейсом.Несколько возможных решений:
Решение 1
Сделать метод универсальным:
interface ISaberpsicologiaExceptionHandler
{
ActionResult Result<TException>(TException exception) where TException : SaberpsicologiaException;
}
public class MovedPermanentlyExceptionHandler : ISaberpsicologiaExceptionHandler
{
public ActionResult Result<TException>(TException exception) where TException : SaberpsicologiaException
{
if (exception is MovedPermanentlyException movedPermanentlyException)
{
var redirectResult = new RedirectResult(movedPermanentlyException.CannonicalUri);
redirectResult.Permanent = true;
return redirectResult;
}
throw new InvalidArgumentException("Exception type not supported", nameof(exception));
}
}
Использование:
Для доступа ISaberpsicologiaExceptionHandler.Result
простоприведение к неуниверсальному базовому интерфейсу ISaberpsicologiaExceptionHandler
независимо от типа реализации
catch (MovedPermanentlyException exception)
{
var handler = Activator.CreateInstance(handlerType) as ISaberpsicologiaExceptionHandler;
handler.Result(exception);
}
Решение 2
Использование специализированных интерфейсов:
// General interface
interface ISaberpsicologiaExceptionHandler
{
ActionResult Result(Exception exception);
}
// Specialized interface
interface IMovedPermanentlyExceptionHandler : ISaberpsicologiaExceptionHandler
{
ActionResult Result(MovedPermanentlyException exception);
}
public class MovedPermanentlyExceptionHandler : IMovedPermanentlyExceptionHandler
{
public ActionResult Result(MovedPermanentlyException exception)
{
var redirectResult = new RedirectResult(exception.CannonicalUri);
redirectResult.Permanent = true;
return redirectResult;
}
#region Implementation of ISaberpsicologiaExceptionHandler
// Explicit interface implementation
ActionResult ISaberpsicologiaExceptionHandler.Result(Exception exception)
{
if (exception is MovedPermanentlyException movedPermanentlyException)
{
return Result(movedPermanentlyException);
}
throw new InvalidArgumentException("Exception type not supported", nameof(exception));
}
#endregion
}
Использование:
Для доступа к ISaberpsicologiaExceptionHandler.Result
просто приведите к не универсальному менее специализированному базовому интерфейсу ISaberpsicologiaExceptionHandler
независимо от типа реализации.
catch (MovedPermanentlyException exception)
{
var handler = Activator.CreateInstance(handlerType) as ISaberpsicologiaExceptionHandler;
handler.Result(exception);
}
Решение 3
Использовать отражение:
interface ISaberpsicologiaExceptionHandler
{
ActionResult Result<TException>(TException exception) where TException : SaberpsicologiaException;
}
public class MovedPermanentlyExceptionHandler : ISaberpsicologiaExceptionHandler
{
public ActionResult Result<TException>(TException exception) where TException : SaberpsicologiaException
{
if (exception is MovedPermanentlyException movedPermanentlyException)
{
var redirectResult = new RedirectResult(movedPermanentlyException.CannonicalUri);
redirectResult.Permanent = true;
return redirectResult;
}
throw new InvalidArgumentException("Exception type not supported", nameof(exception));
}
}
Использование:
Для доступа ISaberpsicologiaExceptionHandler.Result
просто приведение к неуниверсальному базовому интерфейсу ISaberpsicologiaExceptionHandler
независимо от типа реализации
catch (MovedPermanentlyException exception)
{
var handler = Activator.CreateInstance(handlerType) as ISaberpsicologiaExceptionHandler;
MethodInfo reflectedMethod = handlerType.GetMethod("Result");
MethodInfo genericMethod = reflectedMethod.MakeGenericMethod(exception.GetType());
object[] args = {exception};
genericMethod.Invoke(this, args);
}
Решение 4
Рекомендуемое решение.
Используйте правильную конкретную реализацию при вызове:
Я не знаю концепциивашего обработчика исключений.Но так как вы всегда знаете, какое конкретное исключение вы хотите перехватить, вы можете создать правильный экземпляр (использование фабрики на этом этапе также вариант):
try
{
// Do something that can throw a MovedPermanentlyException
}
catch (MovedPermanentlyException e)
{
var movedPermanentlyExceptionHandler = new MovedPermanentlyExceptionHandler();
movedPermanentlyExceptionHandler.Result(e);
}
catch (SomeOtherException e)
{
var someOtherExceptionHandler = new SomeOtherExceptionHandler();
someOtherExceptionHandler.Result(e);
}
Есть и другие решения, поэтому я просто сделаю перерыв,Это просто сводится к тому, чтобы избежать кода, который использует неизвестные универсальные типы, на которые ссылаются члены этого неизвестного типа.Я утверждаю, что это всегда возможно и просто вопрос хорошего дизайна.