簡體   English   中英

將泛型類型的實例作為參數傳遞給泛型類的動態實例

[英]Pass an instance of a generic type as a parameter on a dynamic instance of a generic class

我正在嘗試構建實際上是ExceptionLogCondition類型的動態類型的列表,該類是定義需要消除的異常類型的類以及針對特定異常類型的可選條件謂詞。

問題在於將異常傳遞給IsConditionValid(T e)方法。 我總是得到這個異常:

最佳重載方法匹配'MvcApplication.ErrorLogCondition.IsConditionValid(Exceptions.AjaxOnlyViolationException)'有一些無效的參數

堆棧跟蹤:

在System.Dynamic.UpdateDelegates.UpdateAndExecute2 [T0,T1,TRet](CallSite網站,T0 arg0,T1 arg1)處的CallSite.Target(Closure,CallSite,Object,Exception)處在CONCENTRA.MOS.MvcApplication.ErrorLog_Filtering(Object sender, C:_teamprojects \\ Main \\ Source \\ Global.asax.cs:213行中的ExceptionFilterEventArgs e)(Elmah.ErrorLogModule.OnFiltering(ExceptionFilterEventArgs args)在Elmah.ErrorLogModule.LogException(Exception e,HttpContext context)在Elmah.ErrorLogModule.OnError( System.EventHandler.Invoke處的對象發送者,EventArgs args)(對象發送者,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);
    }
}

我的直覺說我可能會做得有點過頭。 因此,我願意接受其他建議。 不過,我也想知道為什么這行不通。

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更改為接受Exception,然后將其強制轉換為該方法內的T ,或者在調用該方法之前強制對其進行強制轉換。

從代碼提供予扣除 e.Exception.GetBaseException()返回其不是澆注到該類型的一個實例AjaxOnlyViolationException類型。

由於GetBaseException()返回類型為Exception ,所以找不到方法public bool IsConditionValid(Exception e) 您應該在簽名中提供一種具有Exception類型的方法。

但是,這可能不是解決性能問題的更好方法(有關動態,請參見MSDN)。

但是您可以使用List<Predicate<Exception>> ,它可以執行相同的工作,同時減少執行此操作所需的代碼行,恕我直言。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM