簡體   English   中英

在運行時創建的類型,作為泛型類型的類型參數

[英]A Type created at runtime as a Type Parameter for a Generic Type

我有這個senario,我需要為json反序列化提供一個類型,我如何讓它動態化?

這里的代碼使用了一個示例類名(rd.ds.SDK.re.sa),但在實際代碼中,將使用數據庫中的數據構造類型。

Type dynamicalyCreatedAtRuntime = Type.GetType("rd.ds.SDK.re.sa");

var response = webRequest.ReadJsonResponseAs<Result<AnalysisResult<dynamicalyCreatedAtRuntime>>();


public static T ReadJsonResponseAs<T>(this HttpWebRequest webRequest)
{
    using (System.IO.Stream responseStream = webRequest.GetResponse().GetResponseStream())
    {
        using (System.IO.StreamReader sr = new System.IO.StreamReader(responseStream))
        {
            T result = JsonConvert.DeserializeObject<T>(sr.ReadToEnd());

            responseStream.Close();
            return result;
        }                    
    }
}

改為使用JsonConvert.DeserializeObject 這個重載

public static object ReadJsonResponseAs(this HttpWebRequest webRequest, Type type)
{
    using (System.IO.Stream responseStream = webRequest.GetResponse().GetResponseStream())
    {
        using (System.IO.StreamReader sr = new System.IO.StreamReader(responseStream))
        {
            object result = JsonConvert.DeserializeObject(sr.ReadToEnd(), type);

            responseStream.Close();
            return result;
        }                    
    }
}

顯然,您需要將結果視為object 由於在編譯期間您不會知道對象的類型,因此使用泛型或使用反射來調用泛型重載是沒有意義的。


您還應該創建這些類型的非泛型版本: Result<T>AnalysisResult<T>

擁有動態創建類型,如Result<AnalysisResult<dynamicalyCreatedAtRuntime>>在運行時可以用反射來完成,但會有這樣做的好處0。 這是一個重新設計的尖叫。

MethodInfo.MakeGenericMethod用於此目的。

如果可以,我會使用Netwonsoft.JSON (Json.Net)。

var json = ...get request body...
var type = Type.GetType("a.b.c");
var obj  = JsonConvert.DeserializeObject(json, type);

有很多幫助也可以使用Json.NET。 如果您無法控制類,這可能無效,並且需要自定義轉換。

如果您絕對必須調用Generic方法,則需要使用反射來手動構建調用。 這很棘手,可能不值得。

var m = webRequest.GetType().GetMethod("ReadJsonResponseAs");
var func = m.MakeGenericMethod(type);
func.Invoke(webRequest, null); /* invoke func on webRequest object, no params */

您的泛型類型是否深層嵌套? 如果是這樣,您可能需要單獨制作每個級別。

使用反射來獲取方法,然后通過使用MakeGenericMethod提供類型參數來“構造”它:

Type dynamicalyCreatedAtRuntime = Type.GetType("rd.ds.SDK.re.sa");
MethodInfo method = webRequest.GetType().GetMethod("ReadJsonResponseAs");
MethodInfo generic = method.MakeGenericMethod(dynamicalyCreatedAtRuntime );
generic.Invoke(this, null);

暫無
暫無

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

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