使用泛型和反射進行 POST,然后處理 JSON,然后回傳正確的型別及其資料。
問題是我不會提前知道型別是單個物件還是物件串列。所以我的通用回傳型別需要是單個事物或單個事物的串列。(這是 .NET Core 6,所以為什么!在某些地方......)
我該如何處理這個難題?
private static async Task<T> ProcessJsonResponse<TX>(HttpResponseMessage response,
string? returnModel = null)
{
var result = await response.Content.ReadAsStringAsync();
if (returnModel != null)
{
var type = Type.GetType(returnModel);
var obj = (T?)Activator.CreateInstance(type!);
var test = type!.GetMethod("FromJson");
object[] parametersArray = { result };
var tim = test!.Invoke(obj, parametersArray);
if (tim is List<T> nowwhat)
{
//can't return List<t> since the return type is T
}
return (T)tim!;
}
//<snip> other non-relevant code ...
}
uj5u.com熱心網友回復:
此解決方案存在一些問題,難以推理。
此方法從動態語言 (JSON) 獲取資料并將其轉換為靜態語言 (C#)。盡管泛型看起來像是動態的,但實際上并非如此。他們需要在編譯時知道。
考慮到這一點,這個
returnModel論點只會使事情變得混亂。方法是最好不要離開它最好的辦法是在考慮型別之前彌合動態語言之間的差距。在這種情況下,這很容易,JSON 陣列將以
'['字符開頭,因此系統可以根據該字符做出決策正如@DiplomacyNotWar 建議的那樣,您需要一個封裝這兩種輸出型別的回傳型別。Sum 型別很棒,但我個人喜歡將它們留在函式世界中。相反,您可以回傳 a
List<T>,它可以處理這兩種情況// 1. Return a List. This type can encapsulate both use cases private static async Task<List<T>> ProcessJsonResponse<T>(HttpResponseMessage response, bool parseFromJson) { var result = await response.Content.ReadAsStringAsync(); // 2: find out what type you will need BEFORE you do anything type based // this code is inefficient and buggy, but you get the gist bool isArray = result.TrimStart()[0] == '['; if (parseFromJson) { // 3. Have two completely separate execution paths for two different types if (isArray) { // 4. Different method to original FromJsonList var test = typeof(T)!.GetMethod("FromJsonList"); object[] parametersArray = { result }; // I am assuming that this will be a static method invoke return (List<T>)test!.Invoke(null, parametersArray)!; } else { var obj = (T?)Activator.CreateInstance(typeof(T)); var test = typeof(T)!.GetMethod("FromJson"); object[] parametersArray = { result }; var tim = (T)test!.Invoke(obj, parametersArray)!; return new List<T> { tim }; } } //<snip> other non-relevant code ... SHOLD }
uj5u.com熱心網友回復:
這就是我想出的——我將@Shane 的答案標記為正確,因為它讓我走上了正確的軌道,讓我明白自己做錯了什么。這也不完整,因為需要進行更多的錯誤檢查,但這比我最初寫的要好得多。
private static async Task<List<T>> ProcessJsonResponse<TX>.
(HttpResponseMessage response, string? returnModel = null)
{
var result = await response.Content.ReadAsStringAsync();
if (result == "[]")
{
var obj = (T)Activator.CreateInstance(typeof(T));
return new List<T> { obj };
}
if (returnModel != null)
{
var token = JToken.Parse(result);
switch (token)
{
case JObject:
{
var returnObject = JsonConvert.DeserializeObject<T>(result);
return new List<T> { returnObject };
}
case JArray:
return JsonConvert.DeserializeObject<List<T>>(result);
}
}
var model = JsonConvert.DeserializeObject<T>(result);
Debug.Assert(model != null, nameof(model) " != null");
return new List<T> { model };
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/483542.html
上一篇:將任何setter作為引數的方法
