zoukankan      html  css  js  c++  java
  • 【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);
    
  • 相关阅读:
    初探Object Pascal的类(一)
    初探Object Pascal的类(二)
    强制类型转换(Casting)
    初探Object Pascal的类(三)
    子界类型(Subrange types)
    浅析枚举类型(Enumerated types)
    指针(Pointer)
    浅谈WEBGIS运用栅格地图实现原理[更新:Google Maps带来的新型WebGIS设计模式]
    算我给Google本地和E都市做个广告吧
    Google地图的配色问题(以及MapBar和51ditu)
  • 原文地址:https://www.cnblogs.com/guxin/p/csharp-how-to-access-the-list-in-generic.html
Copyright © 2011-2022 走看看