一、场景假设

假设现在有一个泛型类T的实例对象t,该T类的全部信息都未知。

要求:打印输出实例对象t的类名、属性个数、属性名、属性的数据类型、属性值。

二、解决问题

1、我们根据输出的内容要求定义一个实体类如下:

    public class GeneralDataModel
{
/// <summary>
/// 类名
/// </summary>
public string class_name { get; set; } /// <summary>
/// 属性个数
/// </summary>
public int prop_count { get; set; } /// <summary>
/// 单个属性的信息
/// </summary>
public List<PropInfoItem> props { get; set; }
}
public class PropInfoItem
{
/// <summary>
/// 属性名
/// </summary>
public string prop_name { get; set; } /// <summary>
/// 属性数据类型
/// </summary>
public string prop_data_type { get; set; } /// <summary>
/// 属性值
/// </summary>
public string prop_value { get; set; }
}

2、编写一个方法,该方法的主要功能是解析实例对象t,并输出步骤1中格式的内容。方法代码实现如下:

        public static GeneralDataModel DataAnalysis<T>(T t)
{
var data_type = t.GetType();
var propInfo = data_type.GetProperties();
var list = new List<PropInfoItem>();
foreach (var item in propInfo)
{
var e = new PropInfoItem
{
prop_name = item.Name,
prop_data_type = item.PropertyType.Name,
prop_value = item.GetValue(t) == null ? "" : item.GetValue(t).ToString()
};
list.Add(e);
} var res = new GeneralDataModel
{
class_name = data_type.Name,
prop_count = propInfo.Count(),
props = list
}; return res;
}

三、验证方法功能

1、假设现在有一个学生类如下所示:

    public class Student
{
/// <summary>
/// 学号
/// </summary>
public int no { get; set; } /// <summary>
/// 姓名
/// </summary>
public string name { get; set; } /// <summary>
/// 年级
/// </summary>
public string grade { get; set; } /// <summary>
/// 出生年月
/// </summary>
public DateTime birth { get; set; }
}

2、根据该类实例化了一个st对象如下:

   var st = new Student()
{
no = 123456,
name = "张三",
grade = "六年级",
birth = DateTime.Now
};

3、调用DataAnalysis方法解析st,并打印输出结果:

   var res = DataAnalysis(st);
Console.WriteLine(JsonConvert.SerializeObject(res));

4、输出结果如下:

{
"class_name": "Student",
"prop_count": 4,
"props": [
{
"prop_name": "no",
"prop_data_type": "Int32",
"prop_value": "123456"
},
{
"prop_name": "name",
"prop_data_type": "String",
"prop_value": "张三"
},
{
"prop_name": "grade",
"prop_data_type": "String",
"prop_value": "六年级"
},
{
"prop_name": "birth",
"prop_data_type": "DateTime",
"prop_value": "2022/5/7 17:21:12"
}
]
}

5、看到输出结果后,感觉完美的解决了问题。

四、变化无常

1、因为种种原因,学生类增加了两个属性,同时实例化对象的创建形式也变了,变化后的形式如下:

    public class Student
{
public Student()
{ } public Student(string id_card_no, string address)
{
this.id_card_no = id_card_no;
this.address = address;
} /// <summary>
/// 学号
/// </summary>
public int no { get; set; } /// <summary>
/// 姓名
/// </summary>
public string name { get; set; } /// <summary>
/// 年级
/// </summary>
public string grade { get; set; } /// <summary>
/// 出生年月
/// </summary>
public DateTime birth { get; set; } /// <summary>
/// 身份证(受保护类型)
/// </summary>
protected string id_card_no { get; set; } /// <summary>
/// 家庭地址(私有类型)
/// </summary>
private string address { get; set; }
}
   var st = new Student("777888202005071111", "家庭地址私有,暂时不方便透露")
{
no = 123456,
name = "张三",
grade = "六年级",
birth = DateTime.Now
};

2、再次调用DataAnalysis方法解析st,并打印输出结果:

   var res = DataAnalysis(st);
Console.WriteLine(JsonConvert.SerializeObject(res));

3、输出结果如下:

{
"class_name": "Student",
"prop_count": 4,
"props": [
{
"prop_name": "no",
"prop_data_type": "Int32",
"prop_value": "123456"
},
{
"prop_name": "name",
"prop_data_type": "String",
"prop_value": "张三"
},
{
"prop_name": "grade",
"prop_data_type": "String",
"prop_value": "六年级"
},
{
"prop_name": "birth",
"prop_data_type": "DateTime",
"prop_value": "2022/5/7 17:40:21"
}
]
}

4、看到输出结果时,咦?怎么似乎好像哪里不对?新增的两个属性怎么没有被解析并输出呢?

五、反射了解一下?

1、通过种种途径或者查阅其他资料你了解到了反射的相关知识,并找到了一个名为GetRuntimeProperties的方法。

2、修改原先的解析方法代码如下:

    public static GeneralDataModel DataAnalysis<T>(T t)
{
var data_type = t.GetType();
var refPropInfo = data_type.GetRuntimeProperties();
var list = new List<PropInfoItem>();
foreach (var item in refPropInfo)
{
var e = new PropInfoItem
{
prop_name = item.Name,
prop_data_type = item.PropertyType.Name,
prop_value = item.GetValue(t) == null ? "" : item.GetValue(t).ToString()
};
list.Add(e);
} var res = new GeneralDataModel
{
class_name = data_type.Name,
prop_count = refPropInfo.Count(),
props = list
}; return res;
}

3、再一次调用DataAnalysis方法解析st,并打印输出结果:

   var res = DataAnalysis(st);
Console.WriteLine(JsonConvert.SerializeObject(res));

4、输出结果如下:

{
"class_name": "Student",
"prop_count": 6,
"props": [
{
"prop_name": "no",
"prop_data_type": "Int32",
"prop_value": "123456"
},
{
"prop_name": "name",
"prop_data_type": "String",
"prop_value": "张三"
},
{
"prop_name": "grade",
"prop_data_type": "String",
"prop_value": "六年级"
},
{
"prop_name": "birth",
"prop_data_type": "DateTime",
"prop_value": "2022/5/7 17:52:12"
},
{
"prop_name": "id_card_no",
"prop_data_type": "String",
"prop_value": "777888202005071111"
},
{
"prop_name": "address",
"prop_data_type": "String",
"prop_value": "家庭地址暂时不方便透露"
}
]
}

5、看到这输出结果,脸上露出了满意的笑容,啊~~~问题终于解决了,开森^_^

六、前后对比并溯源

1、方法前后变化仅仅只有一处,由GetProperties变为了GetRuntimeProperties

2、溯源发现:

  • GetProperties:在System命名空间下,是Type类的实例方法。
  • GetRuntimeProperties(Type类的扩展方法):在System.Reflection命名空间下,是RuntimeReflectionExtensions类的静态方法。

--------------The  End--------------

----------本篇文章到此结束----------

C# 随机给一个全部信息都未知的类类型,如何获取该类的类名、属性个数、属性名、属性的数据类型、属性值?的更多相关文章

  1. PHP处理上传文件信息数组中的文件类型 正确获取

    PHP处理上传文件信息数组中的文件类型$_FILES['type']由客户端浏览器提供,有可能是黑客伪造的信息,请写一个函数来确保用户上传的图像文件类型真实可靠 如果是一般文件则通过 mime_con ...

  2. 逆向分析objc,所有类的信息都能在动态调试中获取。

    因为objc是动态绑定的,程序运行时必须知道如何绑定,依靠的就是类描述.只要知道类描述是如何组织的就可以获取一切有用的信息.不知道是幸运还是不幸,这些信息全部都在运行的程序中.即使没有IDA这样的工具 ...

  3. 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息

    0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...

  4. 深刻:截获windows的消息并分析实例(DefWindowProc),以WM_NCHITTEST举例(Windows下每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息)

    1,回调函数工作机制 回调函数由操作系统自动调用,回调函数的返回值当然也是返回给操作系统了. 2,截获操作系统发出的消息,截获到后,将另外一个消息返回给操作系统,已达到欺骗操作系统的目的. 下面还是以 ...

  5. python3 - 商品管理的程序,商品信息都存在一个json串里面

    商品管理的程序,商品信息都存在一个json串里面 1.查询商品信息 #校验商品是否存在 2.新增商品 # #校验商品是否存在 #校验价格是否合法 3.修改商品信息 ##校验商品是否存在 if chic ...

  6. 每一个web开发者都应该了解的HTTP/2

    我认为每一个 web 开发者都应该对这个支撑了整个 Web 世界的 HTTP 协议有所了解,这样才能帮助你更好的完成开发任务.在这篇文章中,我将讨论什么是 HTTP,它是怎么产生的,它的地位,以及我们 ...

  7. 利用Python完成一个小游戏:随机挑选一个单词,并对其进行乱序,玩家要猜出原始单词

    一 Python的概述以及游戏的内容 Python是一种功能强大且易于使用的编程语言,更接近人类语言,以至于人们都说它是“以思考的速度编程”:Python具备现代编程语言所应具备的一切功能:Pytho ...

  8. 从SQLite获取数据完成一个产品信息展示

    在ios实际开发当中,我们常常用到Core Data做为数据储存首选.但在处理一些大量复杂的数据值且数据之间相互关联的时候,这就不得不使用关系型数据库来实现.例如一个导航程序,自身应该包含大量的地图自 ...

  9. 61. 从1到n,共有n个数字,每个数字只出现一次。从中随机拿走一个数字x,请给出最快的方法,找到这个数字。如果随机拿走k(k>=2)个数字呢?[find k missing numbers from 1 to n]

    [本文链接] http://www.cnblogs.com/hellogiser/p/find-k-missing-numbers-from-1-to-n.html  [题目] 从1到n,共有n个数字 ...

随机推荐

  1. docker打包镜像,测试部署

    docker基本入门以后,(docker基本入门https://www.cnblogs.com/yangyangming/p/11470926.html)可以试试打包docker镜像与dockerfi ...

  2. 为什么要配置JDK环境变量?

    1. PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin目录增加到现有的PATH ...

  3. idea-spring-boot打包jar/var

    下面的插件配置的里面需要加上具体的main类 <groupId>org.springframework.boot</groupId> <artifactId>spr ...

  4. 学习GlusterFS(二)

    环境准备 3台机器,每个机器双网卡,每个机器还需要额外添加1个10GB的磁盘用于测试 机器系统版本是centos6.6 1 2 3 4 5 [root@gluster-1-1 ~]# uname -r ...

  5. Python - 数据存储与数据库简介

  6. (stm32f103学习总结)—stm32 PMW输出实验

    一.PWM简介 PWM是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调 制,简称脉宽调制.它是利用微处理器的数字输出来对模拟电路进行控 制的一种非常有效的技术,其控制简 ...

  7. 【控制】模型预测控制 MPC 【合集】Model Predictive Control

    1.模型预测控制--运动学模型 2.模型预测控制--模型线性化 3.模型预测控制--模型离散化 4.模型预测控制--预测 5.模型预测控制--控制律优化二次型优化 6.模型预测控制--反馈控制 7.模 ...

  8. css样式权重优先级,css样式优先级

    原文:http://www.bkjia.com/Javascri... 样式选择器权重优先级: important > 内嵌样式 > ID > 类 > 标签 | 伪类 | 属性 ...

  9. 结合Vue.js的前端压缩图片方案

    这是一个很简单的方案.嗯,是真的. 为什么要这么做? 在移动Web蓬勃发展的今天,有太多太多的应用需要让用户在移动Web上传图片文件了,正因如此,我们有些困难必须去攻克: 低网速下上传进度缓慢,用户体 ...

  10. HTML5中新增Javascript特性

    存储 localStorage 存储: window.localStorage.setItem('key', 'value'); 取值: window.localStorage.getItem('ke ...