簡體   English   中英

將異常類型列表作為類型參數傳遞給泛型方法

[英]Passing List of Exception Types as type parameter to generic method

我正在嘗試編寫一個通用的輔助方法,該方法將調用方法並處理異常(如果有)。

該方法應該能夠接受可接受的Exception類型的List ,並以特定方式處理它們。 對於其他類型的異常,它將以不同的方式處理。

這是該方法的非常簡化的版本

public static TResult InvokeMethod<TResult, TAllowedException>
                (Func<TResult> func) where TAllowedException : Exception
{
    try
    {
        return func();
    }
    catch (Exception ex)
    {
        if (ex is TAllowedException) //do something
            return default(TResult);
        else //do something else
            throw;
    }
}

在這里,我將允許的Exception Type指定為TAllowedException 這很好。 但是,這僅接受一個Exception_Type 我該如何傳遞List<Exception_Type>

您不能將類型列表作為類型參數傳遞給泛型方法。

為什么不簡單地將類型的集合作為常規參數傳遞呢?

public static TResult InvokeMethod<TResult>
        (Func<TResult> func, ICollection<Type> ignoredExceptions)
{
    try
    {
        return func();
    }
    catch (Exception ex)                         
        when (ignoredExceptions != null &&                    
              ignoredExceptions.Any(t => t.IsAssignableFrom(ex.GetType())))
    {
        return default(TResult);
    }
}

如果有人傳遞的Type也不例外,則不會發生任何不良情況。 我認為沒有必要對其進行驗證。 該方法仍將正常工作-集合中的異常將被忽略。

調用InvokeMethod(func, new Type[] { typeof(Int32) })的預期行為是什么? func將被執行,並且如果它引發一個Int32異常,則將返回默認結果。 func絕不會拋出Int32異常,因此它已經可以像這樣工作,而無需驗證ignoredExceptions

BTW不需要將arg作為參數傳遞。 您可以使用lambda捕獲閉包中的arg - () => func(arg) 這將適用於任何數量的參數。

編輯

如果您真的想在編譯時限制類型,則必須創建自己的集合,並使用一些奇怪的通用Add方法:

public class ExceptionCollection : IEnumerable<Type>
{
    private readonly List<Type> _exceptions = new List<Type>();        

    public void Add<T>() where T : Exception => _exceptions.Add(typeof(T));
    public IEnumerator<Type> GetEnumerator() => _exceptions.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_exceptions).GetEnumerator();
}

此類的最大缺點是,它不適用於集合初始值設定項。

也有一種方法使其也可以與集合初始化程序一起使用。 初始化程序需要一個帶有一個參數的Add方法,但是它們將很高興地與泛型Add<T>(T item)方法一起工作。

public void Add<T>(T item) where T : Exception => _exceptions.Add(typeof(T));

使用它也有些棘手。 我們當然可以傳遞異常的實例,但是僅創建實例來獲取其類型毫無意義。 我們可以使用強制類型轉換或default(T)來傳遞強類型的null

new ExceptionCollection { default(ArgumentNullException), default(ArgumentException) };

我仍然認為在這種特殊情況下,不必驗證類型的集合。 在其他情況下,如果有必要限制類型的集合,那么上述解決方案就可以了。

暫無
暫無

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

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