原文『论.NET反射、委托技术与设计模式关系』来自areliang的Blog论坛。介绍:委托技术是.NET引入的一种重要技术,使用委托可以实现对象行为的动态绑定,从而提高设计的灵活性。采用委托技术可以进一步实现用组合代替继承的思路,很多采用继承实现的关系可以采用委托实现。采用委托可以简化下列设计模式的使用。(1)模板方法;(2)观察者;(3)中介者。

http://areliang.blogchina.com/2860041.html

论.NET反射、委托技术与设计模式关系

反射技术与设计模式

  反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。
  1、.NET可执行应用程序结构

  程序代码在编译后生成可执行的应用,我们首先要了解这种可执行应用程序的结构。

  应用程序结构分为应用程序域?程序集?模块?类型?成员几个层次,公共语言运行库加载器管理应用程序域,这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。

  程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。反射通常具有以下用途。

  (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。

  (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。

  (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。

  (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。

  (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。

  (6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。

  (7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。

  (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

  System.Reflection.Emit命名空间的类提供了一种特殊形式的反射,可以在运行时构造类型。

  反射也可用于创建称为类型浏览器的应用程序,使用户能够选择类型,然后查看有关选定类型的信息。

  此外,Jscript等语言编译器使用反射来构造符号表。System.Runtime.Serialization命名空间中的类使用反射来访问数据并确定要永久保存的字段,System.Runtime.Remoting命名空间中的类通过序列化来间接地使用反射。

  2、反射技术示例

  下面是反射技术的示例,我们可以在程序去得时动态实例化对象,获得对象的属性,并调用对象的方法。

1Namespace ReflectionExample
2{
3 class Class1
4 {
5 [STAThread]
6 static void Main (string [ ] args)
7 {
8  System.Console.WriteLine(“列出程序集中的所有类型”);
9  Assembly a = Assembly.LoadFrom (“ReflectionExample.exe”);
10  Type[ ] mytypes = a.GetTypes( );
11
12  Foreach (Type t in mytypes)
13  {
14   System.Console.WriteLine ( t.Name );
15  }
16  System.Console.ReadLine ( );
17  System.Console.WriteLine (“列出HellWord中的所有方法” );
18  Type ht = typeof(HelloWorld);
19  MethodInfo[] mif = ht.GetMethods();
20  foreach(MethodInfo mf in mif)
21  {
22   System.Console.WriteLine(mf.Name);
23  }
24  System.Console.ReadLine();
25  System.Console.WriteLine("实例化HelloWorld,并调用SayHello方法");
26  Object obj = Activator.CreateInstance(ht);
27  string[] s = {"zhenlei"};
28  Object bojName = Activator.CreateInstance(ht,s);
29  BindingFlags flags = (BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance|BindingFlags.DeclaredOnly);
30  MethodInfo msayhello = ht.GetMethod("SayHello");
31  msayhello.Invoke(obj,null);
32  msayhello.Invoke(objName,null);
33  System.Console.ReadLine();
34  }
35 }
36}
1using System;
2namespace ReflectionExample
3{
4  public class HelloWorld
5  {
6   string myName = null;
7   public HelloWorld(string name)
8   {
9    myName = name;
10   }
11   public HelloWorld() : this(null)
12   {}
13   public string Name
14   {
15    get
16    {
17     return myName;
18    }
19   }
20   public void SayHello()
21   {
22    if(myName == null)
23    {
24     System.Console.WriteLine("Hello World");
25    }
26    else
27    {
28     System.Console.WriteLine("Hello," + myName);
29    }
30   }
31  }
32}
33

  3、在设计模式实现中使用反射技术

  采用反射技术可以简化工厂的实现。

  (1)工厂方法:通过反射可以将需要实现的子类名称传递给工厂方法,这样无须在子类中实现类的实例化。

  (2)抽象工厂:使用反射可以减少抽象工厂的子类。

  采用反射技术可以简化工厂代码的复杂程度,在.NET项目中,采用反射技术的工厂已经基本代替了工厂方法。

  采用反射技术可以极大地简化对象的生成,对以下设计模式的实现也有很大影响。

  (1)命令模式:可以采用命令的类型名称作为参数直接获得命令的实例,并且可以动态执行命令。

  (2)享元模式:采用反射技术实例化享元可以简化享元工厂。
委托技术与设计模式

  委托技术是.NET引入的一种重要技术,使用委托可以实现对象行为的动态绑定,从而提高设计的灵活性。
  1、.NET中的委托技术

  .NET运行库支持称为“委托”的引用类型,其作用类似于C++中的函数指针。与函数指针不同,委托实例独立于其封装方法的类,主要是那些方法与委托类型兼容。另外,函数指针只能引用静态函数,而委托可以引用静态和实例方法。委托主要用于.NET Framework中的事件处理程序和回调函数。
  所有委托都从System.Delegate继承而来并且有一个调用列表,这是在调用委托时所执行方法的一个链接列表。产生的委托可以用匹配的签名引用任何方法,没有为具有返回类型并在调用列表中包含多个方法的委托定义返回值。
  可以使用的委托Cimbine及Remove方法在其调用列表中添加和移除方法。若要调用委托,可使用Invoke方法,或者使用BeginInvoke和EndInvoke方法异步调用委托。委托类的实现由运行库提供,而不由用户代码提供。

  委托适用于那种在某些语言中需要用函数指针来解决的情况,但是与函数指针不同,它是面向对象和类型安全的。
  委托声明定义一个类,它是从System.Delegate类派生的类。委托实例封装了一个调用列表,其中列出了一个或多个方法,每个方法称为一个可调用实体。对于实例方法,可调用实体由一个实例和该实例的方法组成;对于静态方法,可调用实体仅由一个方法组成。如果用一组合适的参数来调用一个委托实例,则该委托实例所封装的每个可调用实体都会被调用,并且使用上述同一组参数。

  委托实例的一个有用的属性是它既不知道,也不关心其封装方法所属类的详细信息,对它来说最重要的是这些方法与该委托的类型兼容。即只要方法的返回类型和参数表是相同的,则方法与委托类型兼容,方法的名称不一定要与委托类相同。

  定义和使用委托分为声明、实例化和调用3个步骤。委托用委托声明语法声明,如:

delegate void myDelegate( );

  声明一个名为myDelegate的委托,它不带参数并且不返回任何结果,如:

class Test
{
 static void F( )
 {
  System.Console.WriteLine (“Test.F”);
 }
 static void Main ( )
 {
  myeDelegate d = new myDelegate (F);
  d ( );
 }
}

  创建一个myDelegate实例,然后立即调用它。这样做并没有太大的意义,因为直接调用方法会更简单。当涉及其匿名特性时,委托才能真正显示出其效果,如:

void MultiCall (myDelegate d, int count ) {
 for (int I = 0; I < count; I++) {
  d( );
 }
}

  显示一个重复调用 myDelegate的MultiCall 方法,这个方法不知道,也不必知道myDelegate的目标方法的类型、该方法具有的可访问性或者是否为静态。对它来说最重要的是目标方法与myDelegate兼容。

  2、示例

  下面的例子说明了委托的实现,代码如下:

1using System;
2namespace DelegateExample
3{
4 public class TemplateMethod
5 {
6  public delegate float Comp(float a,float b);
7  public Comp myComp;
8  public TemplateMethod()
9  {}
10  public float DoComp(float[] f)
11  {
12   float nf = float.NaN;
13   foreach(float df in f)
14   {
15    if(float.IsNaN(nf))
16     nf = df;
17    else
18     nf = myComp(nf,df);
19   }
20   return nf;
21  }
22
23 }
24}

委托技术与GOF设计模式中委托的关系

  需要指出的是,.NET中的委托技术与GOF在《设计模式》中所提列的委托的意图一致,但在实现方法上有相当大的区别。.NET中的委托更进一步地降低了对象间的耦合性,将静态的组合关系变为运行时的动态组合关系。

  GOF在《设计模式》中定义的委托是:“委托是一种组合方法,它使组合具有与继承同样的复用能力。在委托方式下,有两个对象参与处理一个请求,接受请求的对象将操作委托给它的代理者(delegate),它类似于子类将请求交给它的父类处理。使用继承时,被继承的操作总能引用接受请求的对象。在C++中通过this成员变量,在Smalltalk中则通过self。委托方式为了得到同样的效果,接受请求的对象将自身传给被委托者(代理人),使被委托的操作可以引用接受请求的对象。”

  如果采用.NET的委托技术,上述结构可以更加灵活。Window不引用Rectangle即可实现Area的计算,为此首先声明一个计算面积的委托定义,示例代码如下:

public delegate float Darea();

  然而在Window类中声明与这个代理一致的接口:

class Window
{
 public Darea Area;
}

  这里不需要引用Rectangle类,只是在执行时动态绑定即可:

Rectangle rc = new Rectangle();
Window w = new Window();
w.Area = new Darea(rc.Area);

  这样当调用w的Area时,实际调用的是Reactangel的Area方法。从实现意图上看,.NET的委托更好地实现了GOF所阐述的意图,结构上也更为灵活。但这两种委托解决的不是一个层面的问题,GOF的委托强调的是一种策略,而.NET和委托技术则是具体实现。

  委托技术与设计模式实现

  采用委托技术可以进一步实现用组合代替继承的思路,很多采用继承实现的关系可以采用委托实现。采用委托可以简化下列设计模式的使用。
  (1)模板方法:这种方法采用继承实现具体方法,采用委托可以动态实现方法的组合。

  (2)观察者:可以使用事件委托实现观察者与主题之间的通信。

  (3)中介者:使用委托可以去除工件与中介者之间的耦合关系。

论.NET反射、委托与模式关系 zt- -相关推荐

  1. 反射与工厂模式:早餐店的发展之路

    实际开发中,接口的主要作用是为了不用层提供有一个操作的标准,如果直接实例化了类的操作[用new关键字来实例化],则一定存在耦合问题,可以用工厂模式解决此问题. 接下来用一个店主开早餐店的经历来阐述反射 ...

  2. 设计模式之工厂类模式总结对比、简单工厂模式、工厂方法模式、抽象工厂模式、带反射的工厂模式、例子代码分析、最详细

    1. 题目 假设某公司同时用SqlServer.MySql数据库,即会切换两数据库(不同数据库的sql语句有些许差异),同时,两数据库里均有对Users.Departments表的操作(sql代码不一 ...

  3. Java的反射机制 工厂模式综合讲解【转载自51CTO】

    2019独角兽企业重金招聘Python工程师标准>>> Java的反射机制 工厂模式综合讲解 1.什么叫反射 Java.lang.reflect包下 正常情况下我们可以通过类实例化一 ...

  4. C#三层架构第九课之反射和工厂模式实现多数据库访问

    反射和工厂模式实现不同数据库访问 在之前上课的基础上,使用反射和模唱模式,实现针对不同数据库的动态访问. 在之前的三层架构代码基础上进行修改. 使用三层架构+工厂模式,来实现一个程序访问多个数据库. ...

  5. android+委托列表,在Android适配器中使用委托者模式

    [这是一个线索]适配器君从不甘当线索,同样是设计模式,适配器模式不是今天的主题,今天的主题是在适配器中如何使用委托者模式以明确设计中的各元素的分工. 一个具有适配器View的界面,Activity作为 ...

  6. 关系,关系模式,关系模型区别和联系

    关系:一个关系对应通常说的一张表 关系模式:关系的描述 关系模型:关系模型由关系数据结构,关系操作集合,关系完整性约束三部分组成. 关系和关系模式的区别 关系模式是型,关系是值,关系模式是对关系的描述 ...

  7. 关系模式(关系模式必须遵循)

    关系模式和关系是什么意思? 关系模式和关系:描述模式描述关系的静态结构,由模式名.关系模式所包含的属性及属性值所满足的条件组成模式定义. 委托代理关系有哪些内涵及模式? 委托代理关系有5种模式 (1) ...

  8. java反射学习(2):反射与代理模式

    一 基本代理设计模式 代理模式核心思路,一个接口有两个子类,一个子类完成业务需求,另一个完成辅助功能 假设实现一个功能,张三吃饭 代码如下: 接口 PersonDao.java package com ...

  9. STM32L476rg 低功耗模式关系梳理以及stm32duino Lowpower库的调用关系梳理

    目录 低功耗模式介绍: Sleep mode: Low-power sleep mode : Stop 0,Stop 1 和Stop 2 mode: Standby mode : Shutdown m ...

  10. 企业物流营销组合模式探讨 (zt)

    科学.合理的物流活动是物流企业获得持续竞争优势的一个关键因素,预示着企业把握着巨大的战略潜力.物流活动离不开营销策略的正确运用,只有把物流与营销结合成一个共同的竞争战略,物流系统才能够成为一个有效的系 ...

最新文章

  1. zb如何导出自己画的_zbrush纹理贴图(zbrush怎么导出映射贴图)
  2. python最高版本-python最新版
  3. 节省公司的宽带接入成本
  4. Linux CenOS7下安装ActivetMQ
  5. 分析citibike数据eda
  6. Qt工作笔记-列表的分页显示(Qt Widgets框架)
  7. PHP5.3下加速器ZendGuardLoader安装及故障处理
  8. springboot的三种启动方式
  9. C#中的变量类型var
  10. 190414每日一句
  11. 【优化算法】多目标跟踪优化算法(MTOA)【含Matlab源码 1466期】
  12. chartControl控件常用属性总结
  13. c语言自学路线图,C语言的知识体系图,C语言学习路线图
  14. 虚幻4地形怎么增加层_虚幻周报20200512 | 该来的总会来的!
  15. python下标访问字典的指_python字典下标
  16. 毁灭战士 DOOM 3DO 源代码公开
  17. Ubuntu 20.04 Server 使用命令行设置 IP 地址
  18. ubuntu16.04对比工具Meld安装和使用
  19. C Primer Plus第七章:控制
  20. 1077篇 ! ICCV2019论文接收结果公布(附70篇论文链接抢先读,含Oral) 更新中

热门文章

  1. ubuntu通过iptables设置某一个ip网段禁用所有端口
  2. DRF基类APIView的子类GenericAPIView
  3. TCxGrid 把列移上移下。
  4. 温习SQL server
  5. Web App 前端构建(纯净版)
  6. EXTI外部中断触发:神舟IV
  7. 使用索引的技巧知识点
  8. 加密解密(源自Discuz!NT3.1)
  9. 细说业务逻辑(前篇)
  10. 平均分配,移动欠费催收款数据的分配应用实例