2. What is reflection and reflection?

Source: Internet
Author: User

[Switch] 2. What is reflection and reflection?

[Switch] 2. What is reflection and reflection?

What is reflection?

Reflection refers to the ability of a program to access, detect, and modify its own state or behavior.

Reflection is a kind of capability, so the definition is to explain what it can do.

We usually use reflection to do the following:

  • Obtain information about the type
  • Dynamic call Method
  • Dynamic Object Construction
  • Obtain the type from the dataset.
Obtain information about the type

The core Type class of reflection. The Type object provides attributes and methods to obtain all information about the object, such as methods, fields, attributes, events, and so on.

We can obtain several types of Type objects in the loaded Assembly: (take the StringBuilder Type as an example)

No matter which one we use, the final result is the same.

So what information can we get through Type?

Obtain information about the type itself (namespace name, full name, whether it is abstract, whether it is a class, and so on)
Var T1 = typeof (StringBuilder); Console. writeLine ("namespace name:" + T1.Namespace); Console. writeLine ("direct base type:" + T1.BaseType); Console. writeLine ("Full name:" + T1.FullName); Console. writeLine ("is abstract type:" + T1.IsAbstract); Console. writeLine ("is a class:" + T1.IsClass );//..... and so on.

Get the type member information (use the method GetMembers in Tyep)
Type T1 = typeof (TClass); var Mets = T1.GetMembers (); // obtain all public members of the Type object foreach (var m in Mets) {Console. writeLine ("[" + m. memberType. toString () + "]:" + m. name); // m. memberType is a member type}

What types of members can MemberType contain? For example: (you can go in with F12)

Note: The DeclaringType attribute of MemberInfo returns the type defined by this attribute, while ReflectedType returns the object type for obtaining this attribute.

For example:

Type T2 = typeof (TClass); var Mets = T2.GetMembers (); // obtain all public members (the returned value is a set of MemberInfo types) foreach (var m in Mets) {if (m. name = "Equals") {Console. writeLine ("[" + m. memberType. toString () + "]:" + m. name); // m. memberType is a member type.

// M. DeclaringType; // obtain the class that declares the Member
// M. ReflectedType; // obtain the class object of this instance for obtaining MemberInfo.
}}

Equals in T2, we know this method is defined in Objec and called in TClass, so:

We found that most of the Members getting Type objects are in the isxxx, Getxxx, and Getxxxs formats.

The isxxx format basically determines whether it is of a certain type.

Both Getxxx and Getxxxs put back a certain type and a certain type set. The main types are:

// FieldInfo encapsulates all information about the field (through the GetFields or GetField method of the Tyep object)
// PropertyInfo Type, which encapsulates the property information of the Type (through the GetProperties or GetProperty method of the Type object)
// ConstructorInfo type, which encapsulates the constructor information of the type ;(..........)
// MethodInfo type, encapsulates the method information of the type ;(........)

// The MemberInfo type encapsulates all public members of the type. (** the GetMembers method we mentioned above **)
// EventInfo type, which encapsulates event information of the type ;(.......)
// ParameterInfo type, which encapsulates the parameter information of the method and constructor ;(........)

They are all in the System. Reflection namespace. The detailed instance usage of each isxxx, Getxxx, and Getxxxs will not be demonstrated one by one. It is not much different from the GetMembers usage above.

Dynamic call Method

First, define a class:

Public class TClass {public void fun (string str) {Console. WriteLine ("I'm a fun method and I'm called. "+ Str);} public void fun2 () {Console. WriteLine (" I'm the fun2 method and I'm called. ") ;}Public static void fun3 () {Console. WriteLine (" I Am a fun3 static method, I was called ");}}
Call method 1 (use InvokeMember to call the method)

Call the method fun with Parameters

Type T1 = typeof(TClass);T1.InvokeMember("fun", BindingFlags.InvokeMethod, null, new TClass(), new string[] { "test" });

Call the method fun2 without parameters.

Type T1 = typeof(TClass);T1.InvokeMember("fun2", BindingFlags.InvokeMethod, null, new TClass(), null);

Call static methods

Type T1 = typeof(TClass);T1.InvokeMember("fun3", BindingFlags.InvokeMethod, null, T1, null);

We found a problem. When we call the instance method, we need to upload the instance object to the past. (Some people may say that all the instance objects are in use. I want you to drop the call fart dynamically. In some cases, after an object is added to our instance, we are still not sure that we can only use the method to call it. Then someone said, what if I'm not sure about the instance object? Next we will analyze the dynamics of the Instance Object. Then let's take a look .)

Let's look at the meanings of these parameters.

First: the name of the method to be dynamically called.

The second is an enumeration, indicating that a method is called.

Third: Binder. null is passed and the default value is used.

Fourth, data is transmitted as an instance object (when an instance method is called) or a Type object (when a static method is called ).

Fifth: an array of parameters to be passed to the API.

Call method 2 (Use MethodInfo. Invoke to call the method)
Type T1 = typeof(TClass);T1.GetMethod("fun", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), new string[] { "testfun1" });T1.GetMethod("fun2", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), null);T1.GetMethod("fun3", BindingFlags.Static | BindingFlags.Public).Invoke(T1, null);

 

Actually, the usage is not much different from the above method.

Real dynamic call

The above two methods always determine the known object name and method name when writing code. So can we call objects and methods without knowing their names? The answer is yes. The implementation is as follows:

Console. writeLine ("Enter the object class name"); string className = Console. readLine (); Console. writeLine ("enter the name of the method to be executed"); string funName = Console. readLine (); Type T1 = Type. getType (className); ConstructorInfo ci = T1.GetConstructors () [0]; // obtain the constructor var obj = ci. invoke (null); // instantiate the constructor T1.InvokeMember (funName, BindingFlags. invokeMethod, null, obj, null );

Of course, this code can only be fun2, because the passing parameter is dead. (You can also modify it to execute fun, fun2, and fun3)

The result is as follows: (both the object name and method name are manually entered)

Dynamic Object Construction

First, we define an object:

Public class TClass {public TClass () {Console. WriteLine ("constructor is executed .. ");} Public TClass (string str) {Console. WriteLine (" the constructor with parameters is executed .. "+ Str );}}

Dynamic Object Construction

// Dynamically construct the object. Method 1: Assembly asm = Assembly. getExecutingAssembly (); TClass obj = (TClass) asm. createInstance ("net. tclass ", true); // true: case-insensitive // dynamically constructs an object. Method 2: ObjectHandle handler = Activator. createInstance (null, "net. TClass "); // null: current Assembly obj = (TClass) handler. unwrap (); // dynamically constructs an object. Method 3 (constructor with parameters): Assembly asm2 = Assembly. getExecutingAssembly (); obj = (TClass) asm2.CreateInstance ("net. tclass ", true, BindingFlags. default, null, new string [] {"test"}, null, null); // true: case insensitive

Run:

Get and modify attributes
Var obj = new TClass (); obj. name = "Zhang San"; Type type = typeof (TClass); // obtain the property var Name = type. invokeMember ("name", BindingFlags. getProperty | BindingFlags. public | BindingFlags. instance, null, obj, new object [] {}) as string; Console. writeLine (obj. name); // set the property type. invokeMember ("name", BindingFlags. setProperty | BindingFlags. public | BindingFlags. instance, null, obj, new object [] {"new property ()"}); Console. writeLine (obj. name );

// ====================================
PropertyInfo[] pros = type.GetProperties(---);//
PropertyInfo pro = null;
Var value = pro. GetValue (type); // get the value

Obtain the type from the Assembly to obtain the Assembly where the current code is located (use GetExecutingAssembly)
Assembly ass = Assembly. getExecutingAssembly (); Console. writeLine ("Name of the current collection:" + ass. manifestModule. name); Console. writeLine ("current assembly path:" + ass. location );

 

Load the Assembly through reflection and create type objects in the program

Obtain the type from the set of programs. We usually use more types. For example, the so-called dependency injection and control inversion (this topic will be analyzed in the next blog) will use reflection to retrieve types from the program set.

First, let's take a look at how to obtain types from the program set. We can use the static methods LoadFrom () or Load () provided by the Assembly type, such:

Assembly asm = Assembly.LoadFrom("Demo.dll");Assembly asm = Assembly.Load("Demo");

Differences:

Assembly asm = Assembly. loadFrom ("net.exe"); // you need to add a suffix. You can specify the path, as shown in the following figure: Assembly asm1 = Assembly. loadFrom (@ "C: \ 01 file \ 05Svn \ BlogsCode \ Blogs. web \ bin \ Blogs. BLL. dll "); Assembly asm2 = Assembly. load ("Blogs. BLL "); // The path cannot be specified without a suffix. // Assembly asm3 = Assembly. load (@ "C: \ 01 file \ 05Svn \ BlogsCode \ Blogs. web \ bin \ Blogs. BLL "); // an error will be reported here // Load can be used to Load the assembly or system assembly under the bin directory of the current program // here TClass can be an interface, the dll can be implemented in any way. TClass obj = (TClass) asm2.CreateInstance ("net. tclass ", true); // true: Case Insensitive obj. fun (); // *** call the method in the Dynamically Loaded dll ***

This provides very powerful functions. If we do not reference an assembly, we can also use an assembly outside the program. We can also reference different assemblies based on different situations. We can even directly configure the dll to be loaded during code execution through the configuration file and the implementation method in the dll to be run. (In the next article, we will talk about dependency injection. Students will continue to pay attention to it ~)

As mentioned above, reflection is not a concept but a collective term for a type of operation. Or some capabilities. I don't feel good at answering what reflection is. I can only say what reflection can do. It can dynamically create objects, dynamically call object methods, dynamically read and set attributes and fields, and dynamically load dll files outside the program. The general feeling is that most of them areDynamic.

 

 

Supplement: Cross-assembly reflection

If we reflect A. dll, and A. dll references B. dll, the following error description will pop up when assembly. GetTypes (); // runs to this place.

 

"System. Reflection. ReflectionTypeLoadException Message =" the type of one or more requests cannot be loaded. For more information, retrieve the LoaderExceptions attribute ."

 

In this case, you can

 

Assembly assembly = Assembly. LoadFrom ("A. dll ");
Type type = assembly. GetType ("xxx. myclassname"); // you can specify the Type to be reflected instead of GetTypes. In addition, the application needs to apply the B. dll that A. dll lock depends on.

 

This article synchronizes to C # basic knowledge consolidation Series

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.