C# 随机给一个全部信息都未知的类类型,如何获取该类的类名、属性个数、属性名、属性的数据类型、属性值?
一、场景假设
假设现在有一个泛型类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# 随机给一个全部信息都未知的类类型,如何获取该类的类名、属性个数、属性名、属性的数据类型、属性值?的更多相关文章
- PHP处理上传文件信息数组中的文件类型 正确获取
PHP处理上传文件信息数组中的文件类型$_FILES['type']由客户端浏览器提供,有可能是黑客伪造的信息,请写一个函数来确保用户上传的图像文件类型真实可靠 如果是一般文件则通过 mime_con ...
- 逆向分析objc,所有类的信息都能在动态调试中获取。
因为objc是动态绑定的,程序运行时必须知道如何绑定,依靠的就是类描述.只要知道类描述是如何组织的就可以获取一切有用的信息.不知道是幸运还是不幸,这些信息全部都在运行的程序中.即使没有IDA这样的工具 ...
- 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息
0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...
- 深刻:截获windows的消息并分析实例(DefWindowProc),以WM_NCHITTEST举例(Windows下每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息)
1,回调函数工作机制 回调函数由操作系统自动调用,回调函数的返回值当然也是返回给操作系统了. 2,截获操作系统发出的消息,截获到后,将另外一个消息返回给操作系统,已达到欺骗操作系统的目的. 下面还是以 ...
- python3 - 商品管理的程序,商品信息都存在一个json串里面
商品管理的程序,商品信息都存在一个json串里面 1.查询商品信息 #校验商品是否存在 2.新增商品 # #校验商品是否存在 #校验价格是否合法 3.修改商品信息 ##校验商品是否存在 if chic ...
- 每一个web开发者都应该了解的HTTP/2
我认为每一个 web 开发者都应该对这个支撑了整个 Web 世界的 HTTP 协议有所了解,这样才能帮助你更好的完成开发任务.在这篇文章中,我将讨论什么是 HTTP,它是怎么产生的,它的地位,以及我们 ...
- 利用Python完成一个小游戏:随机挑选一个单词,并对其进行乱序,玩家要猜出原始单词
一 Python的概述以及游戏的内容 Python是一种功能强大且易于使用的编程语言,更接近人类语言,以至于人们都说它是“以思考的速度编程”:Python具备现代编程语言所应具备的一切功能:Pytho ...
- 从SQLite获取数据完成一个产品信息展示
在ios实际开发当中,我们常常用到Core Data做为数据储存首选.但在处理一些大量复杂的数据值且数据之间相互关联的时候,这就不得不使用关系型数据库来实现.例如一个导航程序,自身应该包含大量的地图自 ...
- 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个数字 ...
随机推荐
- 为什么要配置JDK环境变量?
1. PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin目录增加到现有的PATH ...
- Java 中的 HashSet,内部是如何工作的?
HashSet 的内部采用 HashMap 来实现.由于 Map 需要 key 和 value,所以 所有 key 的都有一个默认 value.类似于 HashMap,HashSet 不允许重复的 k ...
- Servlet与JSP之间相互传值问题
一.JSP向Servlet传值 JSP向Servlet传值的方式有三种:URL后面跟参数.form表单提交.在JSP内置对象Session设置值. URL后面跟参数 JSP文件:<a href= ...
- Linux下切换python2和python3
为什么需要有两个版本的Python Python2和Python3不兼容是每个接触过Python的开发者都知道的事,虽说Python3是未来,但是仍然有很多项目采用Python2开发.Linux的许多 ...
- video元素和audio元素相关事件
前言 在利用video元素或audio元素读取或播放媒体数据时,会触发一系列事件,如果用js脚本来捕抓这些事件,就可以对着这些事件进行处理了. 捕抓的方式有两种: 第一种是监听的方式.使用vedio或 ...
- 7步学会在Windows下上架iOS APP流程
之前用跨平台开发工具做了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到App Store试试,于是找同学借了个苹果开发者账号,但没那么简单,还要用到Mac电脑的钥匙串申请发布证书和上传 ...
- EL表达式详解(常用表达式以及取值)
EL表达式 学习总结 一. El表达式概念 二. El中的表达式 1. 算术表达式 2. 比较表达式 3. 逻辑表达式 4. 三元表达式 5. 判空表达式 三.EL 从四个作用域中取值 1. 概念 2 ...
- 使用ABP SignalR重构消息服务(二)
使用ABP SignalR重构消息服务(二) 上篇使用ABP SignalR重构消息服务(一)主要讲的是SignalR的基础知识和前端如何使用SignalR,这段时间也是落实方案设计.这篇我主要讲解S ...
- RESTFUL风格的接口命名规范
1.首先restfulf风格的api是基于资源的,url命名用来定位资源,而不是表示动作,动作通过请求方式进行表示. 2.URL中应该单复数区分,推荐的实践是永远只用复数.比如GET /api/use ...
- maven打包jar到本地仓库
1.执行如下命令 mvn install:install-file -Dfile=guava-28.2-jre.jar -DgroupId=com.google.guava -DartifactId= ...