【C#】訪問泛型中的List列表資料
阿新 • • 發佈:2018-12-26
光看標題的確不好說明問題,下面描述一下問題場景:
已知後端自定義的返回的Json資料結構如下:
response:
{
"message": "返回成功",
"result":
[
{
"name":"AAA",
"age":16
},
{
"name":"BBB",
"age":17
}
],
"state": 1
}
顯然,根據Json的結構,客戶端可以自定義一個類來描述請求的相應結果。
public class Response<T>
{
public string message { get; set; }
public ObservableCollection<T> result { get; set; }
public int state { get; set; }
}
其中response.result內容是一個數組。為了通用性使用泛型T來描述陣列中元素的型別(即用T來表示相應的實體類)。如本例中的元素型別描述為Student類。
public class Student
{
public string name{ get; set ; }
public int age{ get; set; }
}
現在,如果返回的Response型別為Student,而Student類中又包含了一個儲存其他型別的List列表,即Student實體類變成了如下:
response:
{
"message": "返回成功",
"result":
[
{
"name":"AAA",
"list":
[
{
...
},
{
...
}
]
"age":16
},
{
"name":"BBB",
"list":
[
{
...
},
{
...
}
]
"age":17
}
],
"state": 1
}
那麼對應的Student實體類就要新增一個List列表,變成如下:
public class Student
{
public string name{ get; set; }
public int age{ get; set; }
public ObservableCollection<Achievement> list { set; get; } // 假設業務邏輯是實體類是學生的成績
}
問題:
- 如果後臺返回的資料,是一組T型別的陣列,而該T型別中又包含了一個S型別的列表,該如何訪問該列表?
- 換句話說,如何訪問泛型型別中的列表?
下面的例子演示如何訪問泛型中的列表資料,並用一個新的引用來儲存該列表的資料。為了通用性,使用了泛型和反射。
public class MyClass
{
public ObservableCollection<Achievement> AchievementList; // 用於記錄Student中的List列表的內容
/// <summary>
/// response.result只有唯一元素,獲取該元素中的【唯一】列表資料
/// </summary>
/// <typeparam name="T">唯一元素的型別</typeparam>
/// <typeparam name="S">唯一元素中的指定列表屬性中,儲存的實體類型別</typeparam>
/// <param name="proName">本類中儲存返回的唯一元素的列表的引用</param>
/// <param name="listName">元素中的【唯一】列表的屬性名,看實體類</param>
/// <param name="callback ">如果有回撥,就在完成資料獲取後執行該回調</param>
public void GetListDataInResult<T, S>(string proName, string listName, Action callback = null) where T : class
{
// 在呼叫該方法之前,已經獲得了Response資料!
// 獲得response.result中的資料
T item = response.result[0]; // response.result是個陣列,但裡面只有一個Student元素
// 反射出該元素的實體類,即本例中的Student類
Type t = item.GetType();
// 獲得該元素中的List列表資料
PropertyInfo listPropertyInfo = t.GetProperty(listName);
ObservableCollection<S> sourceList = (ObservableCollection<S>)listPropertyInfo.GetValue(response.result[0], null); // 本文的重點
// 給本類中的儲存該列表的引用賦值
PropertyInfo list = this.GetType().GetProperty(proName);
list.SetValue(this, sourceList);
// 如果有回撥,就在完成資料獲取後執行該回調
callback?.Invoke();
}
}
呼叫上面的方法:
GetListDataInResult<Student, Achievement>("AchievementList", "list", null);