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

简介: 1 反射技术与设计模式   反射(Reflection)是。NET中的重要机制,通过放射,可以在运行时获得。NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。
1 反射技术与设计模式

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

  1.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命名空间中的类通过序列化来间接地使用反射。

1.2 反射技术示例

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

 1 namespace  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}

37

 

 1 using  System;
 2 namespace  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}


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

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

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

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

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

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

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

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

  2 委托技术与设计模式

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

  2.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.2示例

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

  

 1 using  System;
 2 namespace  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}

25

  2.3 委托技术与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和委托技术则是具体实现。

  2.4 委托技术与设计模式实现

  采用委托技术可以进一步实现用组合代替继承的思路,很多采用继承实现的关系可以采用委托实现。采用委托可以简化下列设计模式的使用。

  (1)模板方法:这种方法采用继承实现具体方法,采用委托可以动态实现方法的组合。

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

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

相关文章
|
3月前
|
人工智能 前端开发 Devops
.NET技术在现代开发中的作用:.NET技术的核心价值、在现代应用开发中的实际应用、以及面临的挑战与未来趋势。
.NET技术是软件开发领域的核心力量,本文从其核心价值、实际应用及未来挑战三方面进行探讨。它支持多种语言,提供强大的开发工具和丰富的类库,并具备跨平台能力。在现代应用开发中,.NET广泛应用于企业级系统、Web应用、移动应用、云服务和游戏开发等领域。面对性能优化、容器化、AI集成等挑战,.NET持续创新以适应不断发展变化的技术环境。
60 4
|
3月前
|
人工智能 开发框架 .NET
.NET技术的强大功能:.NET技术的基础特性、在现代开发中的应用、以及它如何助力未来的软件开发。
.NET技术是软件开发领域的核心支柱,以其强大功能、灵活性及安全性广受认可。本文分三部分解析:基础特性如多语言支持、统一运行时环境;现代应用如企业级与Web开发、移动应用、云服务及游戏开发;以及未来趋势如性能优化、容器化、AI集成等,展望.NET在不断变化的技术环境中持续发展与创新。
115 4
|
3月前
|
人工智能 物联网 开发者
.NET技术在现代软件开发中的应用愈发广泛和深入
.NET技术是软件开发的关键支柱,本文分为三部分探讨其创新应用:最新进展如.NET 5/6统一平台、性能提升、跨平台支持增强、云集成优化及开源社区贡献;应用场景涵盖微服务架构、物联网、AI/机器学习、游戏及移动应用开发;未来发展潜力在于持续性能优化、云原生支持、新兴技术集成、生态扩张及教育培训加强。.NET正以其强大适应性和创新潜力引领软件开发的新方向。
47 3
|
3月前
|
人工智能 开发框架 .NET
如何掌握.NET技术,引领开发前沿:.NET技术的核心能力、在现代开发中的应用实践、以及如何通过.NET技术实现持续创新。
.NET技术已成为软件开发不可或缺的部分,本文分三部分探讨:核心能力如多语言支持、统一运行时环境、丰富的类库及跨平台能力;现代开发实践包括企业级应用、Web与移动开发、云服务及游戏开发;并通过性能优化、容器化、AI集成等方面实现持续创新,使开发者站在技术前沿。
63 3
|
26天前
|
人工智能 开发框架 C#
C#/.NET/.NET Core技术前沿周刊 | 第 6 期(2024年9.16-9.22)
C#/.NET/.NET Core技术前沿周刊 | 第 6 期(2024年9.16-9.22)
|
26天前
|
人工智能 开发框架 Cloud Native
C#/.NET/.NET Core技术前沿周刊 | 第 9 期(2024年10.07-10.13)
C#/.NET/.NET Core技术前沿周刊 | 第 9 期(2024年10.07-10.13)
|
3月前
|
设计模式 物联网 Android开发
移动应用与系统:探索未来技术的融合之路后端开发中的设计模式探索
【8月更文挑战第21天】随着科技的飞速发展,移动应用和操作系统已经成为我们日常生活中不可或缺的一部分。本文将深入探讨移动应用开发和移动操作系统的相关话题,包括它们的历史、现状以及未来的发展趋势。我们将从移动应用的开发环境、编程语言和工具等方面进行详细的分析,同时也会讨论移动操作系统的特点、优势以及面临的挑战。最后,我们将展望移动应用与系统在未来技术融合中的可能方向和机遇。
130 58
|
26天前
|
数据可视化 NoSQL C#
C#/.NET/.NET Core技术前沿周刊 | 第 8 期(2024年10.01-10.06)
C#/.NET/.NET Core技术前沿周刊 | 第 8 期(2024年10.01-10.06)
|
26天前
|
设计模式 开发框架 C#
C#/.NET/.NET Core技术前沿周刊 | 第 4 期(2024年9.1-9.8)
C#/.NET/.NET Core技术前沿周刊 | 第 4 期(2024年9.1-9.8)
|
2月前
|
人工智能 前端开发 开发工具
解读.NET 技术的开发潜力
本文全面介绍了.NET技术在软件开发领域的核心优势、创新应用及面临的挑战。.NET以其统一的开发平台、强大的工具和跨平台能力,成为企业级应用、Web应用乃至游戏开发的理想选择。然而,在性能优化、容器化及AI集成等方面仍需不断突破。通过积极拥抱开源和社区驱动模式,.NET将持续推动软件开发的进步。
54 1

热门文章

最新文章

  • 1
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    44
  • 2
    C++一分钟之-C++中的设计模式:单例模式
    51
  • 3
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    36
  • 4
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    59
  • 5
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    54
  • 6
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    39
  • 7
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 8
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    102
  • 9
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    74
  • 10
    Go语言设计模式:使用Option模式简化类的初始化
    71