1. What is reflection?
Reflection provides an object that describes the component, module, and type (type). You can use reflection to dynamically create instances of types, bind types to existing objects, or get types from existing objects, and invoke their methods or access their fields and properties. If you use properties in your code, reflection enables you to access them. For more information, see Properties. -----from Microsoft Official.
Microsoft's explanation I think it can. The plain English is that we can use reflection to let us know the location type of information. Similar shows the B-super in life. The Doctor uses the B-ultrasound to see inside the pregnant woman's belly, because the doctor cannot view it from the inside. The reflection is the same for the location type. or a referenced DLL. We are not aware of the internal situation. But it can be reflected. The ultrasound of bats is also. Bounce back through sound waves to see if there are any obstacles ahead. This is the function of reflection. If you want to ask how the reflection interior is implemented. Excuse me. I don't know at the moment. haha haha.
Simply put, our program is made up of DLLs, and there are many classes in the DLL. The class also has fields, properties, and methods. The function of reflection is to give a DLL to know what classes, through the class and can know which members. So how does the reflection in. NET do it? There are several kinds of reflective classes to be introduced below.
(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).
(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.
(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. This passage is from Daniel's blog copy-------> Portal
Here are a few more detailed classes that I'll focus on in turn.
The first is assembly. This exists under the System.Reflection namespace. I mainly talk about the methods and differences of its 3 loading assemblies. Load,loadform,loadfile.
Speaking of this multi-language, first look at the syntax from the code.
Using system;using system.collections.generic;using system.linq;using system.reflection;using System.Text;using System.threading.tasks;namespace Reflection demo{ class program { static void Main (string[] args) { // Load assembly Assembly Assembly = Assembly.Load ("Testdll"); The strong name of the output assembly Console.WriteLine (assembly. FullName); Console.readkey ();}}}
The Load method is to load the program through the name of the Assembly, but the assembly that needs to be loaded is found in the bin directory of the current assembly.
Loadform
Using system;using system.collections.generic;using system.linq;using system.reflection;using System.Text;using System.threading.tasks;namespace Reflection demo{ class program { static void Main (string[] args) { # Region Load Method //loading assembly //Assembly Assembly = Assembly.Load ("Testdll"); The strong name of the output assembly //console.writeline (assembly. FullName); Console.readkey (); #endregion Assembly assmbly1 = Assembly.LoadFrom (@ "C:\Users\DH\Documents\visual Studio 2017\projects\ Reflection demo\ Testdll\bin\debug\testdll.dll "); Console.WriteLine (assmbly1. FullName); Console.readkey ();}}}
Loadform is created by path. Returns the loaded assembly.
Look at the last loadfile.
Using system;using system.collections.generic;using system.linq;using system.reflection;using System.Text;using System.threading.tasks;namespace Reflection demo{class Program {static void Main (string[] args) { #region Load method//loading assembly//Assembly Assembly = Assembly.Load ("Testdll"); The strong name of the output assembly//console.writeline (assembly. FullName); Console.readkey (); #endregion #region LoadFrom method//assembly assmbly1 = Assembly.LoadFrom (@ "C:\Users\DH\Documents\visual Studio 2017\projects\ Reflective Demo\testdll\bin\debug\testdll.dll "); Console.WriteLine (assmbly1. FullName); Console.readkey (); #endregion #region LoadFile method Assembly assmbly2 = Assembly.loadfile (@ "C:\Users\DH\Documents\visual s Tudio 2017\projects\ reflex Demo\testdll\bin\debug\testdll.dll "); Console.WriteLine (Assmbly2. FullName); Console.readkey (); #endRegion}}}
This three method syntax is simple. Now say the three differences, and the pros and cons.
LoadFrom and Load:loadform the same assembly is loaded only once, even if the assembly is loaded with the same path, he can only return you to the previous assembly, LoadFrom can only be used to load different identities of the assembly, that is, the unique assembly, cannot be used to load an assembly that has the same identity but a different path.
LoadFile and Loadform:loadfile only load themselves in assemblies that are not added to their referenced assemblies, Loadform and load are their reference assemblies that will be loaded. And loadfile can only be loaded once for the same assembly. This is the same as Loadform.
From the performance point of view loadform not load good, the function is also a bit stronger load. It is recommended to use load if both LOADFOM and load meet the needs of the application.
There are several overloaded versions of these methods. Since this film is only a basic article. Not too much space. You can find out more about MSN by looking at the documentation. The most detailed description is the documentation. But the document says more official. Combined with the blog that Daniel wrote. A little easier to understand.
Okay, let's get to the next stage. Assembly now we got it. I'm starting to see what's inside the assembly.
Using system;using system.collections.generic;using system.linq;using system.reflection;using System.Text;using System.threading.tasks;namespace Reflection demo{ class program { static void Main (string[] args) { # Region LoadFrom Method Assembly assmbly = Assembly.LoadFrom (@ "C:\Users\DH\Documents\visual Studio 2017\projects\ Reflective Demo\testdll\bin\debug\testdll.dll "); type[] types = assmbly. GetTypes (); foreach (var item in types) { Console.WriteLine ("Class:" +item. Name); } Console.readkey (); #endregion }} }
assmbly. GetTypes () This method or gets all the classes.
Let me show you the fields that get fields and methods
using system;using system.collections.generic;using system.linq;using system.reflection;using System.Text; Using System.threading.tasks;namespace Reflection demo{class Program {static void Main (string[] args) { #region LoadFrom method Assembly assmbly = Assembly.LoadFrom (@ "C:\Users\DH\Documents\visual Studio 2017\projec Ts\ reflex Demo\testdll\bin\debug\testdll.dll "); type[] types = assmbly. GetTypes (); foreach (var classitem in Types) {Console.WriteLine ("Class:" + Classitem. Name); foreach (Var fileditem in Classitem. GetFields ()) {Console.WriteLine ("Field Name:" + Fileditem. Name); } foreach (Var methoditem in Classitem. GetMethods ()) {Console.WriteLine ("Method Name:" +methoditem.name); }} console.readkey (); #endregion}}}
It can be seen that we have reflected the fields and the method names, but there is a problem that our parent's methods are also being made. We can modify the next. This place has an overloaded version. GetMethods has an overloaded method that can filter the parent class by BindingFlags enumeration parameters, or something else. BindingFlags this enumeration type. There's not much to say here. In the future I will gradually fill the whole.
So much for simplicity. Reflection can do a lot of things, very flexible. Reflection is used in our abstract factory. Our factory. It is created by reflection. Below I write a demo demo of its role.
Using system;using system.collections.generic;using system.linq;using system.reflection;using System.Text;using System.threading.tasks;using Testdll;namespace Reflection demo{ class program { static void Main (string[] args) { Assembly assmbly = Assembly.Load ("Testdll"); Sqlserverhelper helper = (sqlserverhelper) assmbly. CreateInstance ("Testdll.sqlserverhelper"); Helper. Query (); Console.readkey ();}}}
Little friends can find. We instantiate a Sqlserverhelper object, but instead of using the normal new method, we use reflection. This time some small partners may say that this is to take off the pants fart, direct new more simple. Here is true, but placed in the real project directly new is then cool, demand changes are waiting to cry, for example, the leader to you that the company's database does not use SQL Server, replaced by Oracle. This is the time to change the code if you are new and it may be more complicated. But with our reflection, this kind of annoyance will not exist.
CreateInstance ("Testdll.sqlserverhelper") This method parameter we can completely modify through the configuration file. This class does not need to change. Let me show you the code.
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Namespace testdll{public interface Idbhelper { void Query (); }}
First, create an interface for the contract data operation Idbhlper class. Specify a query method, then let sqlserverhelper inherit this interface, and implement this method.
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; namespace testdll{public class Sqlserverhelper:idbhelper {public void Query () { Console.WriteLine ("This is the Test");}}}
Then modify the method of the Mian function
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <startup> <supportedruntime version= "v4.0" sku= ". netframework,version=v4.5 "/> </startup> <appSettings> <add key=" Helper "value=" Testdll.sqlserverhelper "/> </appSettings></configuration>
Using system;using system.collections.generic;using system.configuration;using system.linq;using System.Reflection; Using system.text;using system.threading.tasks;using testdll;namespace reflection demo{ class program { static void Main (string[] args) { Assembly assmbly = Assembly.Load ("Testdll"); String helperkey = configurationmanager.appsettings["Helper"]; Idbhelper helper = (idbhelper) assmbly. CreateInstance (Helperkey); Helper. Query (); Console.readkey ();}}}
In this case, if you want to switch the helper inside the Mian function to Oracle, just add a class that inherits from the Idbheper interface, then implement the method, point to the class in the modification configuration file, and then you can. For the main function we do not need to move, this is all we have high cohesion low coupling. Complete the decoupling. Easy to modify.
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; namespace testdll{public class Oraclehelper:idbhelper {public void Query () { Console.WriteLine ("I Am the Orcle database");}}}
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <startup> <supportedruntime version= "v4.0" sku= ". netframework,version=v4.5 "/> </startup> <appSettings> <add key=" Helper "value=" Testdll.oraclehelper "/> </appSettings></configuration>
Using system;using system.collections.generic;using system.configuration;using system.linq;using System.Reflection; Using system.text;using system.threading.tasks;using testdll;namespace reflection demo{ class program { static void Main (string[] args) { Assembly assmbly = Assembly.Load ("Testdll"); String helperkey = configurationmanager.appsettings["Helper"]; Idbhelper helper = (idbhelper) assmbly. CreateInstance (Helperkey); Helper. Query (); Console.readkey ();}}}
The Mian function does not change at all. Run View results
In this case, I have demonstrated a reflection application scenario. In fact, there is a lot of reflection in VS itself. Like what. Creating an Object Call method when vs directly can only help us list the members under this object. This is through reflection. There's actually a lot more. Waiting for everyone to find out. Reflection should be a high-level knowledge point within C #. What is being said is just the tip of the iceberg.
Ok. It's over here, huh? If you have a question about a small partner who has just started learning, you can comment on our study together. If any of Daniel has a random eye on a mistake, please tell me that I can make progress.
6.c# Points of Knowledge: reflection