Передать экземпляр универсального типа в качестве параметра в динамический экземпляр универсального класса - PullRequest
0 голосов
/ 14 февраля 2012

Я пытаюсь создать список динамических типов, который на самом деле имеет тип ExceptionLogCondition, который является классом, который определяет тип исключения, которое должно быть отклонено, и необязательный предикат условия для конкретного типа исключения.

Проблема заключается в передаче исключения в метод IsConditionValid(T e).Я всегда получаю это исключение:

Наилучший перегруженный метод соответствует «MvcApplication.ErrorLogCondition.IsConditionValid (Exceptions.AjaxOnlyViolationException)» с недопустимыми аргументами

Stacktrace:

в CallSite.Target (Closure, CallSite, Object, Exception) в System.Dynamic.UpdateDelegates.UpdateAndExecute2 [T0, T1, TRet] (сайт CallSite, T0 arg0, T1 arg1) в CONCENTRA.MOS.MvcApplication.ErrorLog_Filtering (Отправитель объекта, ExceptionFilterEventArgs e) в C: _teamprojects \ Main \ Source \ Global.asax.cs: строка 213 в Elmah.ErrorLogModule.OnFiltering (ExceptionFilterEventArgs args context.ExceptionLogExceptionExt).в Elmah.ErrorLogModule.OnError (Отправитель объекта, аргументы EventArgs) в System.EventHandler.Invoke (Отправитель объекта, EventArgs e)
в System.Web.HttpApplication.RaiseOnError ()

Воткод:

public class MvcApplication : System.Web.HttpApplication
{
    protected void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
    {
        var exceptionsToDismiss = new List<dynamic>() {
            new ErrorLogCondition<Exceptions.AjaxOnlyViolationException>(),
            new ErrorLogCondition<WebsiteException>(c => c.LogError == true)
        };

        foreach (var exd in exceptionsToDismiss)
        {
            if(((Type)exd.ExceptionType).Equals(e.Exception.GetBaseException().GetType()) &&
                exd.IsConditionValid(e.Exception.GetBaseException()))
                // The second condition fails even though the type is correct (see first if condition).
                e.Dismiss();
        }
    }
}

public class ErrorLogCondition<T> where T : Exception, new() { 
    public Type ExceptionType {get;set;}
    public Predicate<T> ExceptionTypeCondition { get; set; }

    public ErrorLogCondition() {
        ExceptionType = typeof(T);
    }

    public ErrorLogCondition(Predicate<T> c)
    {
        ExceptionType = typeof(T);
        ExceptionTypeCondition = c;
    }

    public bool IsConditionValid(T e)
    { 
        return ExceptionTypeCondition == null || ExceptionTypeCondition.Invoke(e);
    }
}

Мое чувство кишки говорит, что я, возможно, немного переусердствовал.Так что я открыт для других предложений.Тем не менее, я также хотел бы знать, почему это не работает.

Ответы [ 3 ]

3 голосов
/ 14 февраля 2012

GetBaseException() возвращает Exception, а это не то, что IsConditionValid может принять.У вас есть моральный эквивалент этого кода:

Exception baseExp = e.Exception.GetBaseException() //which is a AjaxOnlyViolation
IsConditionValid( baseExp);

//where isconditionvalid is:
bool IsConditionValid(AjaxOnlyViolation e) { }

Неважно, что экземпляр во время выполнения является AjaxOnlyViolation во время выполнения - компилятор этого не знает.Важно то, что объявлено как возможное, что это любое исключение, и не существует неявного приведения от Exception до AjaxOnlyViolation.Поэтому ошибка.

Вам нужно сообщить компилятору;Вы можете либо изменить IsConditionValid, чтобы принимать Исключение, затем привести его к T внутри этого метода, или привести его перед вызовом метода.

1 голос
/ 14 февраля 2012

Поскольку GetBaseException() тип возвращаемого значения - Exception, метод public bool IsConditionValid(Exception e) не найден. Вы должны предоставить метод с типом Exception в подписи.

Тем не менее, это может быть не лучшим подходом к проблемам производительности (см. MSDN о динамике).

Но вы могли бы использовать List<Predicate<Exception>>, который выполнял бы такую ​​же работу, сокращая при этом необходимые строки кода, ИМХО.

1 голос
/ 14 февраля 2012

Из предоставленного кода I вычитает , что e.Exception.GetBaseException() возвращает экземпляр типа, который нельзя преобразовать в тип AjaxOnlyViolationException.

...