1. 程式人生 > >【C#】訪問泛型中的List列表資料

【C#】訪問泛型中的List列表資料

光看標題的確不好說明問題,下面描述一下問題場景:

已知後端自定義的返回的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);