将泛型类型的实例作为泛型类的动态实例上的参数传递

本文关键字:实例 动态 参数传递 泛型类 泛型类型 | 更新日期: 2023-09-27 18:24:25

我正在尝试构建一个动态类型的列表,该列表实际上是类型ExceptionLogCondition,该类定义了需要消除的异常类型和特定异常类型的可选条件谓词。

问题在于将异常传递给IsConditionValid(T e)方法。我总是得到这个例外:

最佳重载方法匹配 'MvcApplication.ErrorLogCondition.IsConditionValid(Exceptions.AjaxOnlyViolationException(' 有一些无效的参数

堆栈跟踪:

at

CallSite.Target(Closure , CallSite , Object , Exception ( at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite 站点,T0 arg0,T1 arg1( at 共中心。苔藓。MvcApplication.ErrorLog_Filtering(对象发送方, ExceptionFilterEventArgs e( in C:_teamprojects''Main''Source''Global.asax.cs:line 213 at Elmah.ErrorLogModule.OnFiltering(ExceptionFilterEventArgs args( at Elmah.ErrorLogModule.LogException(Exception e, HttpContext context( at Elmah.ErrorLogModule.OnError(Object sender, EventArgs args( at System.EventHandler.Invoke(Object sender, EventArgs e(
at 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);
    }
}

我的直觉告诉我可能有点过头了。因此,我愿意接受其他建议。不过,我也想知道为什么这不起作用。

将泛型类型的实例作为泛型类的动态实例上的参数传递

GetBaseException()返回一个Exception,这不是IsConditionValid可以接受的。 您拥有此代码的道德等价物:

Exception baseExp = e.Exception.GetBaseException() //which is a AjaxOnlyViolation
IsConditionValid( baseExp);
//where isconditionvalid is:
bool IsConditionValid(AjaxOnlyViolation e) { }
运行时

的实例在运行时是 AjaxOnlyViolation 并不重要 - 编译器不知道这一点。 重要的是,它被声明为可能的任何例外,并且没有从ExceptionAjaxOnlyViolation的隐式转换。 因此,错误。

你需要告诉编译器; 可以将 IsConditionValid 更改为接受异常,然后将其强制转换为该方法中的T,或者在调用该方法之前强制转换异常。

从提供的代码中,我推断e.Exception.GetBaseException()返回一个不能转换为AjaxOnlyViolationException类型的实例。

由于返回类型GetBaseException() Exception,因此找不到public bool IsConditionValid(Exception e)的方法。应在签名中提供具有Exception类型的方法。

尽管如此,对于性能问题,这可能不是更好的方法(请参阅 MSDN 了解动态(。

但是你可以使用一个List<Predicate<Exception>>,它可以做同样的工作,同时减少所需的代码行,恕我直言。