zoukankan      html  css  js  c++  java
  • 入门反射(一)

    在很多项目的很多地方都发现了一个共同的术语---反射

    有时候我在想这是个什么东西,能干啥。

    这几天静下心来,好好地去翻了翻书,看了看别人的博客。

    也自己比着写了两个泛型反射方法。还算理解了一小部分,写个记录。

    上例子代码:

    这是通过反射工厂来创建实例:

    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);

    总结

    反射我只是初窥门径,如果有错误的地方请各位大佬指正。

    反射肯定不会只输出这些名字。

    反射还可以设置类型里公用的值。还可以调用类型中公用的方法。

    等到下一篇讲吧。

  • 相关阅读:
    Python-Image 基本的图像处理操作
    剪枝
    poj1182(食物链)续
    HLG2035广搜
    HLG2040二叉树遍历已知前中,求后
    先序,中序,后序,已知两者求第三者
    C++中new的解说
    僵尸进程
    HLG2062(make,heap问题)
    make_head,,,pop_head,,,push_head,,,sort_head..
  • 原文地址:https://www.cnblogs.com/yingxl/p/9083515.html
Copyright © 2011-2022 走看看