一、场景假设

假设现在有一个泛型类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. Eclipse建立Web项目,手动生成web.xml文件

    相关文章:https://blog.csdn.net/ys_code/article/details/79156188(Web项目建立,手动生成web.xml文件

  2. 4.RDD操作

    目录 一. RDD创建 从本地文件系统中加载数据创建RDD 从HDFS加载数据创建RDD 通过并行集合(列表)创建RDD 二. RDD操作 转换操作 filter(func) map(func) fl ...

  3. 【Linux-vim】vim文件:查看某几行,把某几行复制到另一个文件中

    一.查看文件的某几行1.使用cat命令(1)查看文件的前10行: cat filename |head -n 10(2)查看文件后10行: cat filename |tail -n 10(3)查看文 ...

  4. Pandas查询数据的几种方法

    Pandas查询数据 Pandas查询数据的几种方法 df.loc方法,根据行.列的标签值查询 df.iloc方法,根据行.列的数字位置查询 df.where方法 df.query方法 .loc既能查 ...

  5. 汽车中的V流程开发

    各步骤的简介各步骤的简介 (1)Control Design and offline Simulation:算法模型构建和离线仿真(基于模型的设计).算法工程师用Matlab模型实现算法:并实施离线仿 ...

  6. 顺利通过EMC实验(16)

  7. 阿里云场景化阿里云企业数字化转型售前方法PSA

    阿里云场景化阿里云企业数字化转型售前方法PSA 目录 01 课程收获 理解企业数字化转型的概念.内涵.本质 了解企业数字化转型的要点.目标和切入点 掌握数字化转型项目售前阶段实践方法 场景化方案 阿里 ...

  8. 用CSS实现Tab页切换效果

    用CSS实现Tab切换效果 最近切一个页面的时候涉及到了一个tab切换的部分,因为不想用js想着能不能用纯CSS的选择器来实现切换效果.搜了一下大致有下面三种写法. 利用:hover选择器 缺点:只有 ...

  9. Java简单登录图形界面

    本文参考与:https://blog.csdn.net/wyf2017/article/details/78831744 https://blog.csdn.net/MengKun822/articl ...

  10. nodejs制作爬虫程序

    在nodejs中,可以通过不断对服务器进行请求,以及本身的fs  =>filesystem 模块和clientRequest模块对网站的资源进行怕取,目前只做到了对图片的趴取!视频文件格式各异, ...