入门反射(一)
在很多项目的很多地方都发现了一个共同的术语---反射
有时候我在想这是个什么东西,能干啥。
这几天静下心来,好好地去翻了翻书,看了看别人的博客。
也自己比着写了两个泛型反射方法。还算理解了一小部分,写个记录。
上例子代码:
这是通过反射工厂来创建实例:
public static T TFactory<T>() where T : class { Type ty = typeof(T); string spaceStr = ty.Namespace; string fullStr = ty.FullName; Assembly ass = Assembly.Load(spaceStr); object ob = ass.CreateInstance(fullStr, true); return (T)ob; }
这是将Datatable里的数据反射到LIst集合中:
public static List<T> ToList<T>(this DataTable dt) { if (dt == null || dt.Rows.Count == 0) { return default(List<T>); } List<T> list = new List<T>(); Type type = typeof(T); PropertyInfo[] per = type.GetProperties(); foreach (DataRow row in dt.Rows) { T entity = Activator.CreateInstance<T>(); foreach (PropertyInfo p in per) { object obj = Convert.ChangeType(row[p.Name], p.PropertyType); p.SetValue(entity, obj); } list.Add(entity); } return list; }
猛地一看是不是有点哇塞~,很酷的感觉。
来看看这个反射是个什么东西吧,按照我的理解+书上的指引来大体粗略的写一下反射
反射
大多数程序都要处理数据,包括读,写,操作和显式数据。
然而,对于某些程序来说,他们操作的不是数字,文本或图形,而是程序和程序类型本身的信息。
有关程序及其类型的数据被称为元数据(matadata),他们保存在程序的程序集中(.dll)。
程序在运行时,可以查看其它程序集或其本身的元数据。一个运行的程序查看本身的元数据或其它程序的元数据的行为叫做"反射"。
反射命名空间:System.Reflection
Type类
BCL(基类库)声明了一个叫做Type的抽象类,他被设计用来包含类型的特性。使用这个类能让我们获取程序使用的类型的信息。
由于Type是抽象类,因此他不能有实例。而是在运行时,CLR(公共语言运行库)从Type(RunTimeType)派生的类的实例,Type包含了类型的信息。
当我们要访问这些实例时,CLR不会返回派生类的引用而是Type基类的引用,
需要了解的Type重要事项:
1.对于程序中用到的每一个类型,CLR都会创建一个包含这个类型的Type类型的对象。
2.程序中用到的每一个类型都会关联到独立的Type类的对象。
3.不管创建的类有多少个实例,只有一个Type对象会关联到所有的这些实例。
如图:一个运行的程序,他有两个MyClass对象和一个OtherClass对象。注意:尽管有两个MyClass的实例,只会有一个Type对象来表示他。
我们可以从Type对象中获取需要了解的有关类型的几乎所有信息。
列一下常用的成员吧。
System.Type类部分的成员。
获取Type对象
object类包含了一个叫做GetType的方法,他返回对实例的Type对象的引用。
由于每一个类型最终都是从object继承的,所以我么可以在任何类型对象上使用GetType方法来获取他的Type对象。
Student stu = new Student();
Type type = stu.GetType();//stu可以时任何一个对象实例化后
下面演示一下一个基类跟派生子类。在foreach循环中输出类的名字以及公用字段的名字。
基类与派生类:
class BaseClass //基类 { public int BaseField = 0; } class DerivedClass : BaseClass //派生类 { public int DerivedField = 0; }
通过反射输出类信息:
BaseClass bc = new BaseClass(); //基类 DerivedClass dc = new DerivedClass();//派生类 BaseClass[] bca = new BaseClass[] { bc, dc }; foreach (var v in bca) { Type type = v.GetType(); Console.WriteLine("Type:{0}",type.Name);//输出类名称 FieldInfo[] fields = type.GetFields();//获取所有公用字段 foreach (var f in fields) Console.WriteLine("Field:{0}",f.Name);//输出公用字段名称 }
输出结果为:
类名与公用属性全部被输出了。
我们还可以通过typeof运算符来获取Type对象。
只需提供类型名作为操作数,他就会返回Type对象的引用(通常都会用在泛型方法中),如代码所示。
Type type = typeof(BaseClass);
总结
反射我只是初窥门径,如果有错误的地方请各位大佬指正。
反射肯定不会只输出这些名字。
反射还可以设置类型里公用的值。还可以调用类型中公用的方法。
等到下一篇讲吧。
上一篇: 什么是轻断食法?真的可以轻松变瘦?
下一篇: 乳房按摩法图解 教你如何正确按摩丰胸