C # reflection-related knowledge learning

Source: Internet
Author: User
Tags mscorlib

1. What is C # 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. C # reflects the relationship between namespaces and accessories

Many people are not clear about this concept. For A. Net programmer, it is necessary to understand these concepts.

The namespace is similar to the Java package, but it is not exactly the same, because the Java package must be placed according to the directory location.. net. It only needs to add references.

What are accessories? In terms of words, just as it is said, before the ultimate .exe or. dll, irrelevant and related things (such as many classes) need to be packaged and assembled together. These things are called accessories. Of course, we can directly understand it as EXE and DLL.

The namespace of an assembly does not have a one-to-one relationship or mutual inclusion. An assembly can have multiple namespaces, and a namespace can also exist in multiple accessories. In this case, we may not understand it. Let's take an example:

 
 
  1. // Assembly:
     

  2. Namespace
    N1

  3. {


  4. Public
     
    Class
    AC1 {...}


  5. Public
     
    Class
    Ac2 {...}

  6. }

  7. Namespace
    N2

  8. {


  9. Public
     
    Class
    AC3 {...}


  10. Public
     
    Class
    Ac4 {...}

  11. }

  12. // Install accessory B:
     

  13. Namespace
    N1

  14. {


  15. Public
     
    Class
    BC1 {...}


  16. Public
     
    Class
    BC2 {...}

  17. }

  18. Namespace
    N2

  19. {


  20. Public
     
    Class
    Bc3 {...}


  21. Public
     
    Class
    Bc4 {...}

  22. }


Both of these accessories have 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 in N1 are AC1 and ac2, And the classes in N2 are Ac3 and ac4.

If we remove the reference to a and then reference B to install the accessories, we can only see BC1, BC2, and bc3 and bc4 under N1 in this application.

Reference A and B at the same time, of course, you can see all the above classes.

Here, we can clearly understand a concept. The namespace only describes the type of a family, such as the Han nationality and Hui nationality; the installation of accessories indicates where a type exists.
An accessory is a type of place where it lives. 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, you must reference this assembly.

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.

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:

 
 
  1. public
     
    interface
     IMediaFormat  

  2. {  

  3. string
     Extension {
    get
    ;}  

  4. 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. Use of C # reflection

The basic concept of reflection is the above. What are the applications of reflection?

(1) obtain the type through reflection

There are two methods 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, that
You can.
You can call the GetType method declared on system. 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 a certain
Interface. If yes, a method of this interface is called:

 
 
  1.   …  

  2.  
    public
     
    void
     Process( 
    object
     processObj )  

  3.  

  4. {  

  5.  Type t = processsObj.GetType();  

  6.  
    if
    ( t.GetInterface(“ITest”) !=
    null
     )  

  7.     …  

  8. }  

  9. … 


Another method to obtain the type is to use the type. GetType and assembly. GetType methods, such:

 
 
  1. 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:

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


(2) traversing object attributes through reflection

There is a test object class:

 
 
  1. Using
    System;

  2. Using
    System. Collections. Generic;

  3. Using
    System. LINQ;

  4. Using
    System. Web;

  5.  

  6. /**/
    /// <Summary>

  7. /// Summary of test
     

  8. /// </Summary>
     

  9. Public
     
    Class
    Test

  10. {


  11. Int
    ID;


  12. String
    Name;


  13. Double
    Score;


  14. Public
    Test ()

  15. {

  16. }


  17. Public
     
    Int
    Id {
    Get
    ;
    Set
    ;}


  18. Public
     
    String
    Name {
    Get
    ;
    Set
    ;}


  19. Public
     
    Double
    Score {
    Get
    ;
    Set
    ;}

  20. }

  21.  


Sometimes I need to traverse the attributes (names and values) of a test object or I am very lazy and there are many attributes of that object class, you can use the following method:

 
 
  1. Protected
     
    Void
    Page_load (
    Object
    Sender, eventargs E)

  2. {

  3. Test test =
    New
    Test ();

  4. Test. ID = 1;

  5. Test. Name =
    "Language"
    ;

  6. Test. Score = 87.5;


  7. Foreach
    (System. reflection. propertyinfo pi
    In
    Test. GetType (). getproperties ())

  8. {

  9. Response. Write (PI. Name +
    ":"
    + Pi. getvalue (test,
    Null
    ). Tostring () +
    "<Br/>"
    );

  10. }

  11. }


You can also use this method to obtain the browser information:

 
 
  1. Protected
     
    Void
    Page_load (
    Object
    Sender, eventargs E)

  2. {
    /**/
    /// Use the reflection mechanism to output the values of each browser attribute


  3. Foreach
    (System. reflection. propertyinfo pi
    In
    Request. browser. GetType (). getproperties ())

  4. {


  5. Object
    OBJ =
    New
     
    Object
    ();


  6. If
    (PI. GetType (). basetype. Name =
    "Propertyinfo"
    )

  7. {
    /**/
    /// Obtain the attribute name and its value, and output it on the page


  8. Try
     

  9. {

  10. Response. Write (PI. Name +
    "="
    + Pi. getvalue (request. browser,
    Null
    ). Tostring () +
    "<Br/>"
    );

  11. }


  12. Catch
     

  13. {


  14. Continue
    ;

  15. }

  16. }

  17. }

  18. }


(3) dynamically create objects based on types

It is the basis for implementing the abstract factory and the core technology for implementing the abstract factory. Through it, You can dynamically create an object you want. The following example shows how to dynamically create an instance of chinesename or englishname.

 
 
  1. Using
    System;

  2.  
    Using
    System. reflection;

  3.  
    Namespace
    Testreflection

  4. {


  5. Class
    Reflectionexample

  6. {


  7. Public
     
    Static
     
    Void
    Main ()

  8. {

  9. INAME name = abstractfactory. getname ();

  10. Name. showname ();

  11. }

  12. }

  13.  


  14. Public
     
    Class
    Abstractfactory

  15. {


  16. Public
     
    Static
    INAME getname ()

  17. {


  18. // The value of S will be dynamically obtained from web. config later
     


  19. // Assign s to testreflection. ishishname. The English name is displayed.
     


  20. String
    S =
    "Testreflection. chinesename"
    ;

  21. INAME name = (INAME) Assembly. Load (
    "Testreflection"
    ). Createinstance (s );


  22. Return
    Name;

  23. }

  24. }



  25. // Declare an interface that displays the "name" Function
     


  26. Public
     
    Interface
    INAME

  27. {


  28. Void
    Showname ();

  29. }

  30.  


  31. // Implement the interface to display the Chinese name
     


  32. Public
     
    Class
    Chinesename: INAME

  33. {


  34. Public
     
    Void
    Showname ()

  35. {

  36. Console. writeline (
    "! "
    );

  37. Console. Readline (
    "Chinese name"
    );

  38. }

  39. }

  40.  


  41. // Implement the interface to display the English name
     


  42. Public
     
    Class
    Englishname: INAME

  43. {


  44. Void
    INAME. showname ()

  45. {

  46. Console. writeline (
    "Enslish name"
    );

  47. Console. Readline ();

  48. }

  49. }

  50. }



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.