core反射的介绍与使⽤
1. 概述反射
通过反射可以提供类型信息,从⽽使得我们开发⼈员在运⾏时能够利⽤这些信息构造和使⽤对象。
反射机制允许程序在执⾏过程中动态地添加各种功能。
2. Type类的介绍
是BCL(基底类别库)声明的⼀个抽象类,所有它不能被实例化
对于程序中⽤到的每⼀个类型,CLR(公共语⾔运⾏时)都会创建⼀个包含这个类型信息的Type类型的对象
程序中⽤到的每⼀个类型都会关联到独⽴的Type类型的对象
不管创建的类型有多少个实例,只有⼀个Type对象会关联到所有这些实例
2.1 Type类的部分常见成员
成员成员类型描述
Name属性返回类型的名字
FullName属性返回数据类型的完全限定名(包括命名空间名)
NameSpace属性返回包含数据类型声明的命名空间
Assembly属性返回声明类型的程序集。如果类型是泛型的,返回定义这个类型的程序集GetConstructor(), GetConstructors()⽅法返回ConstructorInfo类型,⽤于取得该类的构造函数的信息
GetEvent(), GetEvents()⽅法返回EventInfo类型,⽤于取得该类的事件的信息
GetField(), GetFields()⽅法返回FieldInfo类型,⽤于取得该类的字段(成员变量)的信息
GetInterface(), GetInterfaces()⽅法返回InterfaceInfo类型,⽤于取得该类实现的接⼝的信息
GetMember(), GetMembers()⽅法返回MemberInfo类型,⽤于取得该类的所有成员的信息
GetMethod(), GetMethods()⽅法返回MethodInfo类型,⽤于取得该类的⽅法的信息
GetProperty(), GetProperties()⽅法返回PropertyInfo类型,⽤于取得该类的属性的信息
3. 如何获取Type类型
3.1GetType()和typeof() ⽅法两者都是返回Syetem.Type的引⽤。(private和protected修饰的成员也可以访问到)
3.1.1 GetType()
1.GetType()是从Syetem.object中基础的⽅法。
2.GetType()必须要通过类型的实例点出这个⽅法。
3.1.2 typeof()
3.2 不同点
1.GetType()返回的是Type(类型)
1 //实例⼀个⽤户类
2 User user = new User();
3 //GetType()⽅法
4 Type getType = user.GetType();
5 //typeof(xx) ⽅法
6 Type typeOf = typeof(User);
7 //判断是否相等
8 if (getType == typeOf)
9 {
10 //这⾥相等
11 Console.WriteLine("我在这");
12 }
4.Type类⽅法
1:⼀旦有了Type对象就可以使⽤GetMethodInfo()⽅法获取此类型⽀持的⽅法列表。该⽅法返回⼀个MethodInfo 对象数组,MethodInfo对象描述了主调类型所⽀持的⽅法,他位于System.Reflection命名空间中
2: MethodInfo类派⽣于MethodBase抽象类,⽽MethodBase类继承了MemberInfo类。因此我们能够使⽤这三个类定义的属性和⽅法。例如,使⽤Name属性得到⽅法名称。这⾥有两个重要的成员:
3: ReturnType属性:为Type类型的对象,能够提供⽅法的返回类型信息 GetParameters()⽅法:返回参数列表,参数信息以数组形式保存在PatameterInfo 对象中。PatameterInfo类定义了⼤量描述参数信息的属性和⽅法。这⾥也列出两个常⽤的属性:Name(包含参数名称信息的字符串),ParameterType(参数类型的信息)。
//创建实例
Sublevel sublevel = new Sublevel();
//获取类型
Type sublevelType = sublevel.GetType();
//获取类型的⽅法列表
//BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public 这个有⼀个注意点
//实际上⾄少要有Instance(或Static)与Public(或NonPublic)标记。否则将不会获取任何⽅法。
MethodInfo[] obj = sublevelType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
//遍历所有的⽅法
foreach (MethodInfo item in obj)
{
//返回⽅法的返回类型
Console.Write(item.ReturnType.Name);
//返回⽅法的名称
Console.Write(" "+item.Name+"(");
//获取⽅法的返回参数列表
ParameterInfo[] parameterss = item.GetParameters();
foreach (var parameters in parameterss)
{
//参数类型名称
Console.Write(parameters.ParameterType.Name);
//参数名称
Console.Write(" "+parameters.Name+",");
}
Console.WriteLine(")");
}
执⾏的结果,获取了所有的⽅法,包括了⽅法的⽅法名称,⽅法的返回类型,⽅法参数列表。
5.⽅法的使⽤
前⾯我们讲了放的显⽰,但是只能看到不能⽤就不好了呀
5.1:GetMethods()⽅法的另⼀种形式
这种形式可以制定各种标记,已筛选想要获取的⽅法。他的通⽤形式为:MethodInfo[] GetMethods(BindingFlags bindingAttr)BindingFlags是⼀个枚举,枚举值有(很多只列出4个吧)
Instance:获取实例⽅法
NonPublic: 获取⾮公有⽅法
Public:获取共有⽅法
Static:获取静态⽅法
GetMethods(BindingFlags bindingAttr)这个⽅法,参数可以使⽤or把两个或更多标记连接在⼀起,实际上⾄少要有Instance(或Static)与Public(或NonPublic)标记。否则将不会获取任何⽅法。del.GetType();
public static void Method<T>(T model) {
//获取泛性的Type类型
Type objType = model.GetType();
//获取泛性的⽅法列表
MethodInfo[] mthodInfos = objType.GetMethods();
//循环⽅法
foreach (var item in mthodInfos)
{
//获取⽅法的所有参数列表
var parameters = item.GetParameters();
//过滤没⽤⽅法
//1:查看是不是有参数的⽅法
//2:查看这个⽅法的返回类型是不是我们想要的
/
/3:查看这个⽅法的返回类型是不是我们想要的
if (parameters.Any() &&
parameters[0].ParameterType == typeof(int) &&
item.ReturnType != typeof(void))
{
//调⽤⽅法
object[] parametersObj = new object[] { 5 };
//调⽤实例⽅法
//第⼀个参数是我们的实体,后⾯是我们的参数(参数是⼀个数组,多个参数按照顺序来传递,没有参数可以为null)
//如果我们的⽅法是⼀个静态⽅法,这个参数可以为null (不是静态的就会报错)
Console.WriteLine(item.Invoke(model, parametersObj));
}
}
}
6.DataTable转Model(List)
在刚刚学 的时候,我们从数据库查询出⼀个DataTable的时候想要转成Model或者LIst的时候我们需要⼿动的写遍历,超级⿇烦(在没有接触MVC的时候我就是)
/// <summary>
/// DataTable转换
/
// </summary>
public class TransitionDataTable
{
/// <summary>
/// DataTable转换模型
/// </summary>
/// <typeparam name="T">模型类型</typeparam>
/// <param name="obj">模型</param>
/// <param name="data">数据⾏</param>
/// <returns></returns>
public T DataSetBindModel<T>(T obj, DataTable data) where T : class, new()
{
T result = new T();
foreach (DataRow item in data.Rows)
{
result = assignmentClass(obj, item);
}
return result;
}
/// <summary>
/// DataTable转换List
/// </summary>
/
// <typeparam name="T">模型类型</typeparam>
/// <param name="obj">模型</param>
/// <param name="data">数据⾏</param>
rows函数的使用方法及实例/// <returns></returns>
public List<T> DataSetBindList<T>(T obj, DataTable data) where T : class, new()
{
List<T> result = new List<T>();
foreach (DataRow item in data.Rows)
{
result.Add(assignmentClass(obj, item));
}
return result;
}
/// <summary>
/// DataRow 转换成模型
/// </summary>
/// <typeparam name="T">模型类型</typeparam>
/// <param name="obj">模型</param>
/// <param name="row">数据⾏</param>
/// <returns></returns>
private T assignmentClass<T>(T obj, DataRow row) where T : class, new()
{
if (obj == null)
{
obj = new T();
}
Type type = obj.GetType();
//得到类型的所有属性,也就是表对应的实体模型的所有属性
//嗮选⼀下只要公开的
PropertyInfo[] properts = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); if (properts.Any())
{
foreach (PropertyInfo item in properts)
{
if (row.Table.Columns.IndexOf(item.Name) != -1)
{
if (row[item.Name] != null && row[item.Name] != DBNull.Value)
{
item.SetValue(obj, row[item.Name]);
}
}
}
}
return obj;
}
}
View Code
调⽤
static void Show()
{
DataTable data = new BDHelper().GetData("select * from Jack_News_TNews");
News news = new News();
var list = new TransitionDataTable().DataSetBindList(news, data);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论