Reflection (Reflection) is an important mechanism in. NET that, through radiation, can be obtained at runtime for each type of. NET (including classes, structs, delegates, http://www.php.cn/code/11829.html "target=" _blank " > Interfaces, enumerations, and so on, including methods, properties, events, constructors, and so on. You can also get the names, qualifiers, parameters, and so on for each member. With reflection, you can get a sense of each type. If you get the information for the constructor, you can create the object directly, even if the type of the object is not known at compile time.
1,. NET Executable Application Architecture
The program code builds the executable application after compiling, we first need to understand this kind of executable application's structure.
Application architecture is divided into application domains-assemblies-modules-types-members of several levels, the common language runtime loader manages application domains, which include loading each assembly into the appropriate application domain and controlling the memory layout of the type hierarchy in each assembly.
Assemblies contain modules, and modules contain types, and types also contain members, and reflection provides objects that encapsulate assemblies, modules, and types. We can use reflection to dynamically create an instance of a type, bind the type to an existing object or get a type from an existing object, and then invoke a method of the type or access its fields and properties. Reflection typically has the following uses.
(1) Use assembly to define and load assemblies, load list modules in an assembly manifest, and find types from this assembly and create instances of that type.
(2) Use the module to understand the assemblies that contain modules, the classes in modules, and so on, and to get all global methods or other specific non-global methods defined on the module.
(3) Use ConstructorInfo to understand the name of the constructor, arguments, access modifiers (such as pulic or private), and implementation details (such as abstract or virtual). Use the GetConstructors or GetConstructor method of type to invoke a specific constructor.
(4) Use MethodInfo to understand the name of the method, the return type, parameters, access modifiers (such as pulic or private), and implementation details such as abstract or virtual. Use the GetMethods or GetMethod method of type to invoke a specific method.
(5) Use Fiedinfo to understand the name of a field, access modifiers (such as public or private) and implementation details (such as static), and get or set field values.
(6) Add or remove event handlers by using EventInfo to understand the name of the event, the event handler data type, the custom attribute, the claim type, and the reflection type.
(7) Use PropertyInfo to understand the name, data type, claim type, reflection type, and read-only or writable state of the property, and to get or set the property value.
(8) Use ParameterInfo to understand the name of the parameter, the data type, whether it is an input parameter or an output parameter, and the position of the parameter in the method signature.
Classes in the System.Reflection.Emit namespace provide a special form of reflection that can be constructed at run time.
Reflection can also be used to create an application called a type browser that enables the user to select a type and then view information about the selected type.
In addition, language compilers such as JScript use reflection to construct symbol tables. Classes in the System.Runtime.Serialization namespace use reflection to access the data and determine which fields to persist, and the classes in the System.Runtime.Remoting namespace use reflection indirectly through serialization.
Using system;using system.reflection;namespace reflectionexample{class class1{[STAThread] static void Main (string[] A RGS) {System.Console.WriteLine ("List all types in an assembly"); Assembly a = Assembly.LoadFrom ("ReflectionExample.exe"); type[] Mytypes = A.gettypes (); foreach (Type t in mytypes) {System.Console.WriteLine (t.name); } System.Console.ReadLine (); System.Console.WriteLine ("List all methods in HelloWorld"); Type ht = typeof (HelloWorld); MethodInfo [] MIF = ht. GetMethods (); foreach (MethodInfo MF in MIF) {System.Console.WriteLine (MF. Name); } System.Console.ReadLine (); System.Console.WriteLine ("Instantiate HelloWorld, and Invoke SayHello method"); Object obj = activator.createinstance (HT); string [] s = {"Zhenlei"}; Object objname = Activator.CreateInstance (ht,s); BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | bindingflags.static | BindingFlags.Instance | BINDINGFLAGS.DECLAREDONLY); MethodInfo Msayhello = ht. GetmeThod ("SayHello"); Msayhello. Invoke (Obj,null); Msayhello. Invoke (Objname,null); System.Console.ReadLine (); }}}using system;namespace reflectionexample{///<summary>///HelloWorld Summary description. </summary>public class helloworld{string myName = null; Public HelloWorld (string name) {myName = name; Public HelloWorld (): this (null) {} public string Name {get {return myName;} } public void SayHello () {if (myname==null) System.Console.WriteLine ("Hello World"); else System.Console.WriteLine ("Hello," + myName); }}}
Copy Code
3, the use of reflection technology in the design pattern implementation
The use of reflective technology can simplify the implementation of the factory.
(1) Factory Method: By reflection you can pass a subclass name that needs to be implemented to the factory method, so that you do not have to instantiate the class in the subclass.
(2) Abstract Factory: Use reflection to reduce the subclass of the abstract factory.
The use of reflection technology simplifies the complexity of factory code, and in. NET projects, factories using reflection technology have largely replaced the factory approach.
The use of reflection technology can greatly simplify the generation of objects, and the implementation of the following design patterns have a great impact.
(1) Command mode: You can use the type name of the command as a parameter to get an instance of the command directly, and you can execute the command dynamically.
(2) Enjoy meta-mode: Use the reflection technology to instantiate the share to simplify the sharing of the meta-factory.
4.
Overview of Reflections
Reflection definition: The ability to review metadata and collect type information about it. Metadata (the most basic data unit after compilation) is a whole bunch of tables, and when the assembly or module is compiled, the compiler creates a class definition table, a field definition table, and a method definition table. The System.Reflection namespace contains several classes that allow you to reflect (parse) the code of these metadata tables
and reflection-related namespaces (we are accessing reflection information through these namespaces):
System.Reflection.MemberInfo
System.Reflection.EventInfo
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type
System.Reflection.Assembly
Hierarchical model of Reflection:
Note: Hierarchies are one-to-many relationships
The effect of reflection:
1. You can use reflection to dynamically create an instance of a type, bind a type to an existing object, or get a type from an existing object
2. An application needs to load a specific type from a particular assembly at run time so that reflection can be used when a task is implemented.
3. Reflection is primarily applied to class libraries, which need to know the definition of a type in order to provide more functionality.
Application Highlights:
1. Few applications in real-world applications need to use reflection types
2. Dynamic binding with reflection requires sacrificing performance
3. Some metadata information is not available through reflection
4. Some reflection types are used specifically for development of CLR development compilers, so you should realize that not all reflection types are suitable for everyone.
The assembly that reflects the AppDomain
When you need to reflect all the assemblies contained in the AppDomain, the example is as follows:
static void Main { //all assemblies that call the AppDomain through Getassemblies foreach (Assembly Assem in Appdomain.currentDomain.GetAssemblies ()) { //reflects the current assembly's information reflector. reflectonassembly (Assem) } }
Description: Calling the Getassemblies method of an AppDomain object returns an array of System.Reflection.Assembly elements.
Reflection of a single assembly
The above approach is about reflecting all the assemblies of the AppDomain, and we can show the call to one of the assemblies, the system.reflecton.assembly type provides the following three ways:
1. Load method: A highly recommended method, load method with an assembly flag and load it, load will cause the CLR to apply the policy to the Assembly, in the global assembly buffer, the application base directory and the private path to find the assembly, if it cannot find the assembly system throws an exception
2. LoadFrom method: Pass the path name of an assembly file (including the extension), the CLR will load the assembly that you specify, the parameter passed cannot contain any information about the version number, culture, and public key information if the assembly is not found in the specified path to throw an exception.
3. LoadWithPartialName: Never use this method because the application cannot determine the version of the assembly that is being loaded again. The only use of the method is to help those in the. NET Framework to test the client using the. NET Framework to provide some kind of behavior, this method will eventually be discarded.
Note: System. The AppDomain also provides a load method, unlike the static Load method of assembly, the AppDomain's Load method is an instance method that returns a reference to the assembly, assembly static load Imagining sends an assembly in a value wrapper back to the AppDomain that made the call. Try to avoid using the AppDomain's Load method
Get type information with reflection
I'm done with the reflection on the Assembly, and the following is a third level in the Reflection hierarchy model, type reflection
An example of a simple use of reflection to obtain type information:
using System; 2 using Sytem.reflection; 3 class reflecting 4 {5 static void Main (String[]args) 6 {7 reflecting reflect=new Reflecti Ng ();//define a new Self Class 8//Call an Reflecting.exe assembly 9 Assembly MyAssembly =assembly.loadfrom ("Reflecting.exe") 10 Reflect.getreflectioninfo (myassembly);//Get Reflection Information 11} 12//Define a method for getting reflected content void Getreflectioninfo (Asse mbly myassembly) {type[] Typearr=myassemby. GetTypes ();//Gets the type-foreach (type type in Typearr)//Gets details for each type 17 {18//Gets the structure information of the type HTTP://WWW.C NBLOGS.COM/SOSOFT/19 constructorinfo[] Myconstructors=type. GetConstructors; 20//Get field information of type fieldinfo[] Myfields=type. Getfiedls () 22//Get method information at MethodInfo Mymethodinfo=type. GetMethods (); 24//Get attribute information propertyinfo[] Myproperties=type. GetProperties 26//Get event information eventinfo[] Myevents=type. GetEvents; 28} 29} 30}
Copy Code
Several other ways to get a type object:
1. The System.Type parameter is a string type that must specify the full name of the type (including its namespace)
2. System.Type provides two instances of the method: Getnestedtype,getnestedtypes
3. The instance method provided by the Syetem.Reflection.Assembly type is: gettype,gettypes,getexporedtypes
4. System.Reflection.Moudle provides these instance methods: Gettype,gettypes,findtypes
Set a member of a reflection type
www.cnblogs.com/sosoft/
The member of the reflection type is the bottom layer of data in the reflection hierarchy model. We can get a member of type through the GetMembers method of the Type object. If we are using a getmembers with no parameters, it returns only the public-defined static variables and instance members of that type, we can also return the specified type member by using the parameter's getmembers with the argument setting. The specific parameters refer to the detailed description of the System.reflection.bindingflags enumeration type in MSDN.
For example:
Set the member content of the type that needs to be returned
BindingFlags bf=bingdingflags.declaredonly|bingdingflags.nonpublic| Bingdingflags.public; foreach (MemberInfo mi int t.getmembers (BF)) { WriteLine (mi.membertype)//output specified type member }
Create an instance of a type by reflection
By reflection, you can get the type of the assembly, and we can create a new instance of that type based on the type of assembly that was obtained, which is also the feature of late binding to create an object at run time, as mentioned earlier
We can do this in several ways:
1. The CreateInstance method of System.activator. The method returns a reference to the new object. For specific use see MSND
2. The createinstancefrom of System.activator is similar to the previous method, but requires specifying the type and its assembly
3. Methods of System.AppDomain: Createinstance,createinstanceandunwrap,createinstrancefrom and Createinstracefromandunwrap
4. System.Type InvokeMember Instance method: This method returns a constructor that matches the incoming parameter and constructs the type.
5. Invoke instance method for System.reflection.constructinfo
interface of Reflection type
If you want to get a collection of all the interfaces inherited by a type, you can call the type findinterfaces getinterface or getinterfaces. All of these methods can only return interfaces that are directly inherited by that type, and they do not return interfaces inherited from an interface. The underlying interface to return the interface must call the above method again.
Performance of Reflection:
Using reflection to invoke a type or trigger method, or to access a field or property, the CLR needs to do more: Verify the parameters, check permissions, and so on, so the speed is very slow. So try not to use reflection for programming, for applications that intend to write a dynamically constructed type (late binding), you can do this in one of several ways:
1. The inheritance relationship through the class. Let the type derive from a compile-time-aware underlying type, generate an instance of the type at run time, place a reference to it in a variable of its underlying type, and then invoke the virtual method of the underlying type.
2. Implemented through an interface. At run time, build an instance of the type, place a reference to it into a variable of its interface type, and then invoke the virtual method defined by the interface.
3. Implemented by a delegate. Let the type implement a method whose name and prototype match a delegate that is known at compile time. Constructs an instance of the type at run time, then constructs an instance of the delegate with the object and name of the method, and then invokes the method you want through the delegate. This method is relatively less efficient than the previous two methods.