C # Reflection mechanism learns and uses reflection to obtain type information

Source: Internet
Author: User
Tags modifiers

Reflection (Reflection) is an important mechanism in. NET that, through radiation, can get members of each type in. NET, including classes, structs, delegates, interfaces, and enumerations, including methods, properties, events, constructors, and so on, at run time. 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 of 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.

usingSystem;usingSystem.Reflection;namespacereflectionexample{classclass1{[STAThread]Static voidMain (string[] args) {System.Console.WriteLine ("list all types in an assembly"); Assembly a= Assembly.LoadFrom ("ReflectionExample.exe"); Type[] Mytypes=a.gettypes (); foreach(Type tinchmytypes)    {System.Console.WriteLine (t.name);    } System.Console.ReadLine (); System.Console.WriteLine ("List all the methods in HelloWorld"); Type HT=typeof(HelloWorld); MethodInfo [] MIF=ht.    GetMethods (); foreach(MethodInfo MfinchMIF) {System.Console.WriteLine (MF.       Name);    } System.Console.ReadLine (); System.Console.WriteLine ("instantiate the HelloWorld and call the 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 (); }   }}usingSystem;namespacereflectionexample{/// <summary>///a summary description of the HelloWorld. /// </summary> Public classhelloworld{stringMyName =NULL;  PublicHelloWorld (stringname) {MyName=name; }    PublicHelloWorld (): This(NULL)   {   }    Public stringName {Get     {returnMyName;} }    Public voidSayHello () {if(myname==NULL) System.Console.WriteLine ("Hello World"); ElseSystem.Console.WriteLine ("Hello,"+myName); }}}

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.EventInfoSystem.Reflection.FieldInfoSystem.Reflection.MethodBaseSystem.Reflection.ConstructorInfoSystem . Reflection.MethodInfoSystem.Reflection.PropertyInfoSystem.TypeSystem.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:

staticvoidmain{// Call all assemblies of the AppDomain via Getassemblies foreach( AssemblyasseminAppdomain.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 that is different from the static load method of assembly, which is an instance method of the AppDomain's Load method, and returns a reference to the assembly. The static load imagining of the assembly sends the Assembly back to the AppDomain that made the call by value encapsulation. 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:

Usingsystem;usingsytem.reflection;classreflecting{staticvoidmain (string[]args] {Reflectingreflect=newreflecting ();//define a new self-class//calling a Reflecting.exe assemblyassemblymyassembly=Assembly.LoadFrom ("Reflecting.exe") Reflect.getreflectioninfo (myassembly);//Get reflection Information}//define a method to get reflected contentVoidgetreflectioninfo (assemblymyassembly) {Type[]typearr=myassemby. GetTypes ();//Get Typeforeach(Typetypeintypearr)//get more information for each type{//Get structure information for a typeconstructorinfo[]myconstructors=type. GetConstructors;//get field information for a typefieldinfo[]myfields=type. Getfiedls ()//Get method Informationmethodinfomymethodinfo=type. GetMethods ();//Get Property Informationpropertyinfo[]myproperties=type. GetProperties//Get event Informationeventinfo[]myevents=type. getevents; }}}

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

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:

// sets the member content of the type that needs to be returned bindingflagsbf=bingdingflags.declaredonly|bingdingflags.nonpublic| Bingdingflags.public; foreach (Memberinfomiintt.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 Findinterfacesgetinterface 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.

C # Reflection mechanism learns and uses reflection to obtain type information

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.