簡體   English   中英

C# 在運行時訪問泛型類型參數的實例

[英]C# Access instance of generic type argument at runtime

我的 Polly IAsyncPolicy 有一個句柄異常方法,定義如下:

Handle<ApiException>(ApiException ex)
{
 /// do stuff
} 

ApiException 可以是泛型或非泛型:

public class ApiException

public class ApiException<TResult>

我知道泛型類型的實例將有一個 TResult 類型的名為 Result 的屬性,它總是從名為 BaseResponse 的類型繼承。

有許多從 BaseResponse 繼承的類。 我想避免為它們都編寫異常處理程序並在一個處理程序中完成所有操作。

在運行時,我想

a) 確定 ex 是 ApiException 的泛型或非泛型實例,並且

b)如果它是通用的,則獲取對實例的引用,並訪問“結果”屬性

我可以使用 ex.GetType().IsGenericType 輕松完成 a)

b) 證明很麻煩

我努力了:

        if (ex is ApiException<> apiE)
        {

        }

但我需要一個類型為 go 在<>

我知道該類型將始終從名為BaseResponse的類型繼承,所以我嘗試了,

        if (ex is ApiException<BaseResponse> apiE)
        {

        }

但它不夠具體,並為子繼承者返回 false,例如ApiException<AuthResponse> where AuthResponse: BaseResponse

有什么可以做的嗎?

您確實可以獲取泛型參數的類型,也可以使用反射讀取該Result 您是否可以用它做任何有意義的事情取決於。

static void Handle<T>(T ex) where T : ApiException
{
    var type = typeof(T);
    if(!type.IsGenericType)
    {
        Console.WriteLine($"{type} is non generic");
    }
    else
    {
        var gType = type.GetGenericArguments()[0];
        Console.WriteLine($"{type} is generic, the type is {gType}");
        
        var result = type.GetProperty("Result");
        var obj = (BaseResponse)result.GetValue(ex);
        Console.WriteLine($"Got Result={obj.Name}");
    }
        
}

現場示例: https://dotnetfiddle.net/DpyZpk


我的“視情況而定”評論是在我注意到你評論之前

我只需要訪問所有 TResult 都將從其繼承的基礎 TBaseResult 上的屬性

所以你很幸運......你可以投射那個Result

var obj = (BaseResponse)result.GetValue(ex);
// You can call any methods/properties on the base  type

暫無
暫無

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

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