C# 反射

参考以下文章:
http://www.cnblogs.com/binfire/archive/2013/01/17/2864887.html C# 反射机制
https://blog.youkuaiyun.com/sibaison/article/details/70168338 C#装配件
https://bbs.youkuaiyun.com/topics/60376191 程序集与装配件是不是同一个概念
https://www.cnblogs.com/CHNMurphy/p/8607752.html C# 中使用反射的优缺点
https://www.cnblogs.com/weloveshare/p/5754553.html c# 早绑定晚绑定
https://bbs.youkuaiyun.com/topics/391968018 为什么反射效率那么低?

编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。元数据是编译以后的最基本数据单元,就是一大堆的表。

反射:审查元数据并收集关于它的类型信息的能力。这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,

System.reflection命名空间包含的几个类,允许你通过反射获得这些元数据表的信息。
System.Reflection.Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。(编译好的程序是由多个装配件组成,每个装配件里都包含了元数据,元数据中就存储了自描述信息,如接口、类型、方法等细节,分别描述每个装配件的内容,并可以判断装配件是否装满,还可调用其它装配件的信息。.NET运行时就会加载这个程序装配件,并利用装配件的自描述功能来验证装配件程序的合法性,合法才运行。)
System.Type类可以获得对象的类型信息,包括:方法、构造器、属性等。
System.Reflection.MethodInfo包含方法的信息,包括:方法的名称、参数、返回值等。

反射的优点:
反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
反射的缺点:
性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因为反射是要动态的获取实例调用方法,这就要消耗资源去查找和计算。反射的过程中有递归和遍历的操作,这些都需要时间。     
模糊程序的内部逻辑:反射代码比相应的直接代码更复杂,因而会带来维护问题。程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术。

早绑定 early binding:这种方式运行效率高.
在编译的时候就已经却确定了将来程序运行基类或者派生类的哪个方法。
在编译代码的时候根据引用类型就决定了运行该引用类型中定义的方法。即基类方法。

晚绑定 late binding:
只有在运行的时候才能决定运行基类或者派生类中的方法,C#中用new和override实现了晚绑定。
运行的时候将根据该实际类型,而不是引用类型来调用相应的方法,即取决于我们new了什么对象。

动态绑定 dynamic binding
dynamic声明变量的好处是,编译器在编译时并不知道它引用对象的确切类型,而要到运行时才知道。因此,我们可以通过动态绑定在运行时来操作一些类型的属性、方法等。

DLR(动态语言运行时)使得C#中可以调用动态语言以及使用dynamic的动态类型。它允许添加动态语言,如ruby python。

为什么使用反射?
通俗的说,反射可以使用未知的dll。
你直接引用DLL,那是静态的,一旦改变DLL,就必须重新编译,生产新的软件,但是动态引用DLL就不需要。
反射可以用来开发程序插件一类的,别人开发的插件只要继承某个已知的接口,就可以利用反射动态加载进来,然后实例化接口调用,就可以载入别人的插件了。猜想,不开源的插件使用,那为什么不直接使用命名空间呢?
你提供接口别人提供这个接口的实现,但是不给你源码不给你方法说明,那么这个时候你就只有用反射调用它的实现,以接口形式来使用了。常见的IOC就是这样组织人民这样干的东西。
就举一个例子吧,如果程序中某个地方需要实例化整个程序中所以继承某接口的类,这个时候难道你要去程序中找到所有符合条件的类再实例化?而反射就可以很好的解决这个问题。
dll各种版本的变化,你不可能每次都编译成同一个版本,这样管理会混乱。
这样子也是一种很好的我解藕方式,你如果dll很庞大,引用进工程是不会很方便的。

https://bbs.youkuaiyun.com/wap/topics/390584105 C# 为什么要用反射,什么情况必须使用反射。
https://bbs.youkuaiyun.com/topics/390149930 C#中使用反射的意义?为什么要使用反射

具体操作如下:

http://www.cnblogs.com/dw039/p/7476011.html C# 反射、与dynamic最佳组合
https://blog.youkuaiyun.com/lianjiangwei/article/details/47207875【C#】:浅谈反射机制
 

1,拿到需要的类型,创建对象,操作变量,调用函数。
2,如何拿到需要的类型?如果需要的类型是内部的,是确定的,那就不需要加载程序集,直接使用就行,如果是外部的,或者是不确定的,则需要加载相应的程序集。
3,无论如何,我们需要的不过就是能创建对象,调用函数,操作变量。

//加载DLL,如果是内部的,就不需要加载dll
Assembly ass = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory+"bin\\WebApplication1.dll");
//获得类型,如果是确定的,直接使用该类型就好,如果是不确定,一般通过string参数来传递该类型
Type t = ass.GetType("WebApplication1.MainPage");
//创建实例对象,使用var会更加方便
object o = Activator.CreateInstance(t);
//操作变量
t.GetProperty("Age").SetValue(instance, 18, null);
//调用方法
MethodInfo mi = t.GetMethod("RunJs1");   mi.Invoke(o, null});
//使用dynamic动态类型,直接拿到对象,调用方法
dynamic dy = Activator.CreateInstance(t); dy.RunJs1();

使用反射实现工厂模式如下:

using System.Reflection;

public class ReceiveTest : MonoBehaviour
{
    public void CallFun(string name)
    {
        dynamic tmp = Activator.CreateInstance(Type.GetType(name));//根据name来决定使用哪个对象实例
        tmp.Fun();
    }
}

public interface IFruitTest
{
    void Fun();
}

public class AppleTest : IFruitTest
{
    public void Fun()
    {
        Debug.Log("AppleTest Fun");
    }
}

public class OrangeTest : IFruitTest
{
    public void Fun()
    {
        Debug.Log("OrangeTest Fun");
    }
}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值