浅析C#种的反射

1.前言

以前也写过几篇关于反射的博客(简单反射机制),但都理解的不是很深刻,现在在做项目中又一次的用到了反射,在此再总结一下,对于反射的理解。

2.什么是反射?

最近看博客,才理解了反射无处不在,我们经常用到的VS中的智能提示,就是通过反射获取到类的属性,方法等。反射就是动态获取程序集中的元数据来操作类型的。说的通俗一点,反射就是直接调用Bin文件夹下的.dll来创建对象,调用成员,摆脱了以前通过实例化也就是New操作的方法来调用对象的方法。

小结:反射就是直接调用.dll来创建对象,反射让创建对象的方式发生了变化。

3.什么是程序集(Assembly)

程序集是.net中的概念,比如.net中的.exe或者.dll文件都是程序集。可以把其看做是一堆相关的类的打包。比如包含一些资源文件、类型元数据等

其中调用Assembly(程序集)的GetTypes()方法可以得到程序集中定义的所有的类型

调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息

3.Type类介绍

Type类是实现反射的一个重要的类,通过它可以获取类中所有的信息包括方法、属性等,通过它可以设置属性或者调用方法。

4.重要的类

Assembly:表示一个程序集,它是一个可重用、可自我描述的公共语言运行时应用程序构造块。

Type:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。

MethodInfo:发现方法的属性并提供对方法元数据的访问。

PropertyInfo:发现属性 (Property) 的属性 (Attribute) 并提供对属性 (Property) 元数据的访问。

看了上图,就明白了反射其实就是另外一种机制,另外一种直接通过.dll文件来动态的创建类的对象。

5.Demo

以下是关于这方面知识,自己联系的Demo

<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ClassLibrary1.dll");
            //动态加载一个程序集
            //C:\Users\ZHOU\Desktop\lianxi\ConsoleApplication2\bin\Debug
            Assembly ass = Assembly.LoadFile("C:/Users/ZHOU/Desktop/lianxi/ConsoleApplication2/bin/Debug/ClassLibrary1.dll");
            //获取程序集中公共的类型,通常指的是public的类
            Type[] types = ass.GetExportedTypes();
            foreach (Type type in types)
            {
                //类的名字
                Console.WriteLine(type.Name);
                //类的全名称(命名空间.类名)
                Console.WriteLine(type.FullName);
            }

            //可以获取到所有的类,包括的是私有的类
            //Type[] typ= ass.GetTypes();

            foreach (Type item in types)
            {
                Console.WriteLine(item.Name);
            }
            Console.Read();

            //使用FileCommon的默认构造函数创建对象
            object o = ass.CreateInstance("commom.FileCommon");

            Type t = o.GetType();

            //使用指定参数的构造函数创建对象
            object oo = Activator.CreateInstance(t, "zs", 18);

            //判断student类型的对象,是否可以赋给person。类型的引用调换
            bool r = typeof(Person).IsAssignableFrom(typeof(Student));

            //判断学生对象是不是某个类的实例
            Student b=new Student();
            Type d=typeof(Student);
            bool f=d.IsInstanceOfType(b);

            //判断是不是某个类的子类
            bool z = typeof(Person).IsSubclassOf(typeof(Student));
            #region 动态获取程序集中的属性

            //GetProperties获取类型中的所有属性
            PropertyInfo[] pis = d.GetProperties();

            foreach (PropertyInfo pi in pis)
            {
                if (pi.Name == "Name")
                {
                    //动态给属性赋值
                    pi.SetValue(b, "jk", null);
                    pi.GetValue(b);
                }
            }
            #endregion

            //Type :描述类型的
            //methodInfo:描述方法

            #region 动态获取方法

            MethodInfo[] mis = d.GetMethods();
            foreach (MethodInfo mi in mis)
            {
                //获取子类中的扩展方法
                if (mi.IsSpecialName)
                {
                }
            }

            #endregion

            //动态调用Student类的SayHi方法
            MethodInfo mid = d.GetMethod("Add");
            mid.Invoke(d, null);

            //也可以通过获取的type类型直接调用
            b.Add();
        }
    }

    interface Person
    {
        int Add();
    };

    class Student : Person
    {
        public int Add()
        {
            throw new NotImplementedException();
        }
    }

}
</span>

总结:反射其实就是另外一种创建对象的机制,只不过更灵活而已,关于以上提到的几个类,MSDN上有详细的解释,里面有很多可以用到的方法,想学习的可以查一下。



时间: 2024-10-11 17:39:01

浅析C#种的反射的相关文章

《BI那点儿事》浅析十三种常用的数据挖掘的技术

原文:<BI那点儿事>浅析十三种常用的数据挖掘的技术 一.前沿 数据挖掘就是从大量的.不完全的.有噪声的.模糊的.随机的数据中,提取隐含在其中的.人们事先不知道的但又是潜在有用的信息和知识的过程.数据挖掘的任务是从数据集中发现模式,可以发现的模式有很多种,按功能可以分为两大类:预测性(Predictive)模式和描述性(Descriptive)模式.在应用中往往根据模式的实际作用细分为以下几种:分类,估值,预测,相关性分析,序列,时间序列,描述和可视化等. 数据挖掘涉及的学科领域和技术很多,有

Java并发编程:浅析几种线程安全模型 [转]

多线程编程一直是老生常谈的问题,在Java中,随着JDK的逐渐发展,JDK提供给我们的并发模型也越来越多,本文摘取三例使用不同原理的模型,分析其大致原理.目录如下: 1.COW之CopyOnWriteArrayList 2.CAS之ConcurrentHashMap 3.读写分离之LinkedBlockingQueue COW之CopyOnWriteArrayList cow是copy-on-write的简写,这种模型来源于linux系统fork命令,Java中一种使用cow模型来实现的并发类是

浅析三种特殊进程:孤儿进程,僵尸进程和守护进程.

其实有时想想linux内核的设计也蕴含着很多人生哲学,在linux中有这么几个特殊进程中,我们一开始见到它们的名字可能还会觉得很诧异,但在了解完了原理后,我们仔细想想,这样的命名也不无道理!下面我就给大家分别介绍一下这三种特殊的进程! 1.孤儿进程 如果父进程先退出,子进程还没退出那么子进程将被 托孤给init进程,这是子进程的父进程就是init进程(1号进程).其实还是很好理解的. #include <sys/types.h> #include <unistd.h> #inclu

浅析10种常见的黑帽seo手法

虽然博主并不认同黑帽seo手法,但是一些常见的黑帽手法还是需要了解的,增加自己对黑帽的认知,也可以在自己优化网站时适时的规避开这些黑帽手法,从而避免自己的网站被搜索引擎惩罚.好了,话不多说,下面进入今天的主题:10种常见的黑帽手法详解. 1.关键词堆积 这是老生常谈的问题,最常见的一种黑帽seo手法.在网站的内容中,我们讲究的是自然出现关键词,没必要出现时就不要出现,而有些人单纯的为了提升关键词的"密度"在文章中刻意并大量出现关键词,其引出的后果是语句不通顺,严重影响用户的阅读体验,导

使用反射的四种方法

反射是.net提供的用来访问类或者类里面的内容的一项技术,它允许你在编译时对一个类基本上一无所知的情况下对一个类进行访问,支持利用一个字符串对类进行发现.访问.调用等,以下利用实例介绍四种使用反射的方法 首先祭出一个类,用于模拟被调用的类 public class TestClass { private string testType; public string TestType { get { return testType; } set { testType = value; } } pr

C# 之 反射性能优化3

阅读目录 开始 用Delegate优化反射的缺点 用Delegate优化反射的优点 用CodeDOM优化反射的优点 如何用好CodeDOM? 用CodeDOM优化反射的缺点 能不能不使用委托? 根据反射密集程度选择优化方法 CodeDOM优化的误区 反射优化的总结 在前二篇博客中,我分别介绍了二种优化反射的方法: 1. Delegate:委托. 2. CodeDOM:动态代码生成. 这是二种截然不同的方法,性能的差距也很大. 今天的博客将着重比较它们的优缺点,以及给出它们的使用建议. 回到顶部

java 反射机制:运行时的类信息(为框架服务的Bug存在)

反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 换一种引出反射的说法是:当通过反射与一个未知的类型的对象打交道是,JVM只是简单地检查这个类,看它是属于哪个特定的类(就想RTTI那样).在用它做其他事情之前必须先加载那个类的Class对象.因此,那个类的.class文件对于JVM来说必须是可获取的:那么在本地机器上,要么通过网络获得

C#之反射

反射是.NET的一个强大工具,通常我们很少用到反射,但是在开发一些框架或公共类库的时候使用反射会使系统架构更加灵活.了解反射能够加深我们对.NET框架的理解程度.关于反射对性能的影响,可以参考这篇文章:反射是否真的会让你的程序性能降低? 简单来说,反射提供这样几种能力:查看和遍历类型和类型成员的元数据:动态创建类型实例,动态调用所创建的实例的方法.字段.属性:迟绑定方法和属性. 元数据就是描述数据的数据.比如说,一个类可能是一个数据.这个类是否是公共的?这样的描述就是元数据的一种.反射通过Sys

C# 实现AOP 的几种常见方式

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的中统一处理业务逻辑的一种技术,比较常见的场景是:日志记录,错误捕获.性能监控等 AOP的本质是通过代理对象来间接执行真实对象,在代理类中往往会添加装饰一些额外的业务代码,比如如下代码: class RealA { public virtual string Pro { get; set; } public virtual void ShowHello(string