C # reflection

Source: Internet
Author: User
Tags mscorlib

1. What is reflection?
2. Relationships between namespaces and accessories
3. What is the purpose of obtaining type information during runtime?
4. How to Use reflection to obtain the type
5. How to dynamically create objects based on types
6. How to obtain methods and dynamic call Methods
7. dynamically create Delegation

1. What is reflection?
Reflection, which is translated into Reflection in Chinese.
This is.. Net ,. net applications are composed of several parts: 'assembly ', 'module', and 'Type (class) '. Reflection provides a programming method, this allows programmers to obtain relevant information about these components during the running period, for example:

The Assembly class can obtain information about running accessories, dynamically load the accessories, find the type information in the accessories, and create instances of this type.
The Type class can obtain the Type information of an object. This information includes all elements of the object, such as methods, constructors, and attributes. The Type class can obtain and call the information of these elements.
MethodInfo contains information about the method. You can use this class to obtain the name, parameter, and return value of the method and call it.
For example, FieldInfo and EventInfo are included in the System. Reflection namespace.

2. Relationships between namespaces and accessories
Many people may not be clear about this concept. It is necessary to clarify this concept for qualified. Net programmers.
The namespace is similar to a Java package, but it is not exactly the same, because the Java package must be placed according to the directory structure, and the namespace is not required.

The assemblies are the units where the .netapp executes. All the compiled .dllw..exe files are accessories.

The relationship between accessories and namespaces is not one-to-one and does not contain each other. One Accessory can have multiple namespaces, and one namespace can also exist in multiple accessories, this may be a bit vague. For example:
Assembly:

 

namespace   N1{      public   class   AC1   {…}      public   class   AC2   {…}}namespace   N2{      public   class   AC3   {…}      public   class   AC4{…}}

Assembly B:

namespace   N1{      public   class   BC1   {…}      public   class   BC2   {…}}namespace   N2{      public   class   BC3   {…}      public   class   BC4{…}}

Both of the accessories have two namespaces, N1 and N2, and each declares two classes. This is completely acceptable. Then we reference assembly A in an application, in this application, we can see that the classes below N1 are AC1 and AC2, And the classes below N2 are AC3 and ac4.
Then we remove the reference to A and add the reference to B, then the classes under N1 that we can see in this application become BC1 and BC2, and the same is true under N2.
If we reference these two accessories at the same time, we can see the following four classes in N1: AC1, AC2, BC1, and BC2.

Here, we can clearly understand a concept. The namespace only indicates the type of the family, such as the Han nationality and Hui nationality, and the accessories indicate the type of the family, for example, if someone lives in Beijing or Shanghai, then there are Han people in Beijing, Hui people in Shanghai, Han people in Shanghai, and Hui people. This is not a conflict.

As we have mentioned above, accessories are a place where the types reside. To use a class in a program, you must tell the compiler where the class lives before the compiler can find it, that is to say, the accessory must be referenced.
So when you write a program, you may not be sure where the class is, but you only know its name, can you use it? The answer is yes. This is reflection, that is, to provide this type of Address while the program is running, and find it.
If you are interested, let's take a look.

3. What is the purpose of obtaining type information during runtime?
Some people may wonder why the code can be written during development and is still executed at runtime, which is not only tedious but also inefficient.
This is a matter of opinion, just like early binding and late binding. Some people are opposed to late binding on the grounds of waste efficiency, but many people do not realize that they have used late binding when enjoying the benefits of virtual functions. This question is open. It's not clear in just a few words, so it's just a few minutes.
In my opinion, late binding can bring a lot of convenience in design. Proper use can greatly improve the reusability and flexibility of the program, but everything has two sides, it must be measured over and over again.

Next, what is the purpose of obtaining the type information during the runtime?
For example, many software developers prefer to leave some interfaces in their own software. Others can write some plug-ins to expand software functions. For example, I have a media player, I hope that the format of recognition can be easily extended in the future, so I declare an interface:

public   interface   IMediaFormat{string   Extension   {get;}Decoder   GetDecoder();}

This interface contains an Extension attribute, which returns a supported Extension, and another method returns a Decoder object (here I assume a Decoder class, this class provides the function of decoding the file stream, which can be derived from the extension plug-in). I can interpret the file stream through the decoder object.
In this case, all decoding plug-ins must derive a decoder and implement this interface. In the GetDecoder method, return the decoder object and configure its type name to my configuration file.
In this way, I do not need to know the type of the extended format when developing the player. I only need to obtain the type names of all decoder types from the configuration file, the dynamic creation of media format objects is used to convert them to the IMediaFormat interface.

This is a typical application of reflection.

4. How to Use reflection to obtain the type
First, let's look at how to obtain the type information.
There are two methods to obtain the type information. One is to obtain the instance object.
At this time, I only get this instance object. The method may be an object reference or an interface reference, but I don't know its exact type. I need to know, then you can call System. the GetType method declared on the Object to obtain the type Object of the Instance Object. For example, in a method, I need to determine whether the passed parameter has implemented an interface. If yes, then, a method of this interface is called:

…public   void   Process(   object   processObj   ){Type   t   =   processsObj.GetType();if(   t.GetInterface(“ITest”)   !=null   )                    …}…

Another method to obtain the Type is to use the Type. GetType and Assembly. GetType methods, such:
Type t = Type. GetType ("System. String ");
Note that we have mentioned the relationship between namespaces and accessories. To find a class, you must specify its accessories, or call GetType on the obtained Assembly instance.
In this Assembly, only the type name can be written, and the other exception is mscorlib. dll, the type declared in this Assembly can also omit the Assembly name (. by default, mscorlib is referenced during the compilation of Net accessories. dll, unless it is explicitly specified during compilation), for example:
System. String is declared in mscorlib. dll. The above Type t = Type. GetType ("System. String") is correct.
System. Data. DataTable is declared in System. Data. dll, so:
Type. GetType ("System. Data. able") can only get null references.
Required:
Type t = Type. GetType ("System. Data. able, System. Data, Version = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089 ");

5. How to dynamically create objects based on types
System. Activator provides methods to dynamically create objects based on types, such as creating a DataTable:

Type t = Type. GetType ("System. Data. able, System. Data, Version = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089 ");

DataTable table = (DataTable) Activator. CreateInstance (t );

Example 2: Create an object based on the parameter Constructor

 

Namespace TestSpace {public class TestClass {private string _ value; public TestClass (string value) {_ value = value ;}}}... Type t = Type. getType ("TestSpace. testClass "); Object [] constructParms = new object [] {" hello "}; // The constructor parameter TestClass obj = (TestClass) Activator. createInstance (t, constructParms );...

Put the parameters in an Object array in order.

6. How to obtain methods and dynamic call Methods

namespace   TestSpace{      public   class   TestClass   {          private   string   _value;          public   TestClass()   {          }          public   TestClass(string   value)   {                _value   =   value;          }          public   string   GetValue(   string   prefix   )   {           if(   _value==null   )           return   "NULL";           else             return   prefix+"   :   "+_value;            }            public   string   Value   {set   {_value=value;}get   {if(   _value==null   )return   "NULL";elsereturn   _value;}            }      }}

The above is a simple class that contains a constructor with parameters, a GetValue method, and a Value attribute. We can obtain and call the method by using the method name, for example:

// Obtain the type information
Type t = Type. GetType ("TestSpace. TestClass ");
// Parameters of the constructor
Object [] constuctParms = new object [] {"tietong "};
// Create an object based on the Type
Object dObj = Activator. CreateInstance (t, constuctParms );
// Obtain method information
MethodInfo method = t. GetMethod ("GetValue ");
// Some flag spaces of the call method. This field indicates Public and instance method, which is also the default value.
BindingFlags flag = BindingFlags. Public | BindingFlags. Instance;
// Parameters of the GetValue Method
Object [] parameters = new object [] {"Hello "};
// Call a method and use an object to receive the returned value
Object returnValue = method. Invoke (dObj, flag, Type. DefaultBinder, parameters, null );

Properties are similar to method calls. For details, refer to the MSDN

7. dynamically create Delegation
Delegate is the basis for implementing events in C #. Sometimes it is inevitable to dynamically create a Delegate. In fact, Delegate is also a type: System. Delegate. All delegates are derived from this class.
System. Delegate provides some static methods to dynamically create a Delegate, such as a Delegate:

Namespace TestSpace {
Delegate string TestDelegate (string value );
Public class TestClass {
Public TestClass (){
}
Public void GetValue (string value ){
Return value;
}
}
}

Example:
TestClass obj = new TestClass ();

// Obtain the type. In fact, you can use typeof to obtain the type.
Type t = Type. GetType ("TestSpace. TestClass ");
// Create a proxy, input the type, object for creating the proxy, and method name
TestDelegate method = (TestDelegate) Delegate. CreateDelegate (t, obj, "GetValue ");

String returnValue = method ("hello ");

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.