【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);
原文地址:https://www.cnblogs.com/guxin/p/csharp-how-to-access-the-list-in-generic.html