Objective
There are two reasons to write this essay on C # Reflection:
The first one is that the website you develop needs to use
The second is not to see this aspect of the relatively good article.
So make up your mind to write an article, not much nonsense to start to get to the point.
Pre-preparation
Create a new console application in VS2012 (my name is Reflectionstudy), this project is based on . NET 4.0. Then we open the Program.cs file and write our own class in program as follows:
1 Public class Refclass 2 {3 private int _test3; 4 private int _test1 {get; set;} 5 protected int T Est2 {get; set;} 6 public int Test3 {get, set;} 7 8 public void Show () 9 {ten }12 }
Peering inside
As the saying goes tse Baizhanbudai , so our first step is also the key step is to peep at the structure of Refclass class (here we assume that the Refclass do not understand).
First we have to look at the global to continue in depth , so we first write the following code in Main :
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 memberinfo[] Minfos = T.getmembers (); 5 foreach (MemberInfo minfo in Minfos) 6 {7 Console.WriteLine (Minfo. Name); 8 } 9 Console.readkey ();
Here we get the type of the class, and then get the public members of it (many people would think that GetMembers is getting all, but actually just getting all the members exposed. We then loop through the names of all the members through a foreach output.
Then we can look at the output of the console:
Here we can see that not only the members of the class we write are exported, but also the members of the parent class (if you do not understand it here to help you add the base, object is the base class for all classes.) , the attentive reader will surely find that the output here does not contain members with private and protected access rights. This should be the sentence above:GetMembers Returns the public member by default.
Just seeing these open members means little to us, so we need to look at those non-public members.
Let's change the code above to read as follows:
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 memberinfo[] Minfos = T.getmembers (Bi Ndingflags.nonpublic | BindingFlags.Instance | BindingFlags.Public); 5 foreach (MemberInfo minfo in Minfos) 6 {7 Console.WriteLine (Minfo. Name); 8 } 9 Console.readkey ();
From here we see that we used the overloaded version of GetMembers and passed in the enumeration type, which is " contains nonpublic ", " contains instance member ", and " Contains the public . Then we can get all the members.
In the end, we will draw the following members:
Here you might think that we have retrieved the end, but have you found a lot of properties, and also contain a lot of attributes in the parent class, suppose we only focus on the members of the class, and do not care about the members of the parent class how to do it?
In fact, we just need to add an enumeration type (BindingFlags.DeclaredOnly):
1 memberinfo[] Minfos = t.getmembers (BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BINDINGFLAGS.DECLAREDONLY);
Then we'll look at the results:
Only members in that class are included at this time.
Let's add two static methods to the Refclass class as follows:
1 Public class Refclass 2 {3 private int _test3; 4 private int _test1 {get; set;} 5 protected int T Est2 {get; set;} 6 public int TEST3 {get; set;} 7 8 private static void Show2 () 9 { }11 12
public static void Show3 () }15 public void Show () + }20 }
Then we continue to look, and we can see that the final result does not output these static members. At this point we just need to add an enumeration to the GetMembers :bindingflags.static .
Here we just output all the members, but we don't distinguish between the method or the property, so we add a method to Main :
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 func<memb Ertypes, string> GetType = (x) + 5 {6 switch (x) 7 {8 Case Membertypes.field:9 {Ten return "field"; 11 }12 case Membertypes.method:13 {return "method" ;}16 case Membertypes.property:17 {18 return "attribute";}20 default:21 {22 return "Unknown";}24}25};26 Memberi nfo[] Minfos = t.getmembers (BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static ) (MemberInfo minfo in Minfos), (Minfo. Console.WriteLine). Name + "; Type:" + GetType (minfo. MemberType));}31 Console.readkey (); 32}
Here I use a local method to output the corresponding text according to the type, because I have only judged a few basic types for the reason of space.
The results of the final output are as follows:
So far we have been able to peep the whole structure.
Deep Peek Field
We just look at the whole thing through the above, we're going to go deeper, first we start with the field.
Here we are not using GetMembers and need to use GetFields(of course, as with GetMembers if you do not pass in the specified enumeration to return only the exposed fields), the code looks like this:
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 fieldinfo[] Finfos = T.getfields (Bind Ingflags.nonpublic | BindingFlags.Public | BindingFlags.Instance | BINDINGFLAGS.DECLAREDONLY); 5 foreach (FieldInfo finfo in Finfos) 6 {7 Console.WriteLine ("Field name: {0} field type: {1}", Finfo. Name, Finfo. Fieldtype.tostring ()); 8 } 9 Console.readkey ();
The final output results are as follows:
All the way up here everybody thinks we're just analyzing, feeling there's nothing real, here's something real, you can see _test3,_test1 and Test2 are private and protection type,
It is not possible to get their values , but we can do so by reflection, the exact code is as follows:
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 refclass rc = new Refclass (); 5 R C.TEST3 = 3; 6 fieldinfo[] Finfos = t.getfields (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BINDINGFLAGS.DECLAREDONLY); 7 foreach (FieldInfo finfo in Finfos) 8 {9 Console.WriteLine ("Field name: {0} field type: {1} RC has a value of: {}", Finfo. Name, Finfo. Fieldtype.tostring (), Finfo. GetValue (RC)); }11 Console.readkey ();
You can see that I instantiated this class, and set the Test3 to 3, below I pass finfo. GetValue Output This value, the results are as follows:
Are you feeling a little cool now? It's not over yet, we're not getting anything, we're going to change the value of it:
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 refclass rc = new Refclass (); 5 R C.TEST3 = 3; 6 fieldinfo[] Finfos = t.getfields (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BINDINGFLAGS.DECLAREDONLY); 7 foreach (FieldInfo finfo in Finfos) 8 {9 finfo. SetValue (RC, +); Console.WriteLine ("Field name: {0} field type: {1} RC has a value of: {2}", Finfo. Name, Finfo. Fieldtype.tostring (), Finfo. GetValue (RC)); }12 Console.readkey ();
Here I just added a statement finfo in the foreach . SetValue (rc,100), let's continue to look at the results of the final output:
Do you feel like you can do it now? But it's not finished yet.
Deep Peek Properties
Because a property has get and set, and both are methods, it is tricky. We need to get the get and set methods through property objects before they reach the value of modifying this property by calling them.
For example, the following code:
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 Refclass RC = new Refclass (); 5 RC. TEST3 = 3; 6 propertyinfo[] Finfos = t.getproperties (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BINDINGFLAGS.DECLAREDONLY); 7 foreach (PropertyInfo finfo in Finfos) 8 {9 MethodInfo GetInfo = Finfo. Getgetmethod (True); Console.WriteLine ("The name of the Get method {0} returns a value type: {1} parameter number: {2} MSIL code length: {3} local variable number: {4}", Getin Fo. Name, GetInfo. Returntype.tostring (), GetInfo. GetParameters (). Count (), GetInfo. Getmethodbody (). Getilasbytearray (). Length, GetInfo. Getmethodbody (). Localvariables.count); MethodInfo SetInfo = Finfo. GetSetMethod (True); Console.WriteLine ("Get method name {0} return value type: {1} parameter number: {2} MSIL code length: {3} local variable number: {4}", Setin Fo. Name, SetInfo. Returntype.tostring (), SetInfo. GetParameters (). Count (), SetInfo. Getmethodbody (). Getilasbytearray (). length,19 SetInfo. Getmethodbody (). Localvariables.count); SetInfo. Invoke (RC, new object[] {123}), and the object obj = GetInfo. Invoke (RC, NULL); Console.WriteLine ("Method name: {0} internal value: {1}", Finfo. Name, obj);}25 console.readkey (); 26}
Here we loop through each property, get the get method through Getgetmethod (when calling the method if passing in true fails to get the nonpublic get method set is the same), and then we output the return type of the method and the number of parameters and the length of the MSIL code , and the number of local variables ,
Of course, if you are interested in the analysis of input parameters and local variables, and so on, because of the length of the reason can not introduce too much. Finally we call the set method to change the value, and then get the value of the property by calling the Get method.
The final result is as follows:
Deep Peek Method
First we need to modify the Refclass as follows:
1 Public class Refclass 2 {3 private int _test3; 4 private int _test1 {get; set;} 5 protected int T Est2 {get; set;} 6 public int TEST3 {get; set;} 7 8 private static void Show2 () 9 {Ten }12 13
public static string Show3 (string s), { int b;16 int c;17 return s;18 }19 public string Show (string s) { a;23 return s;24 }25 }
The main is to add a local variable in the method and add the return value, avoid the last output when there is no value. In fact, the method here is similar to the Properties section, but in order to be able to describe all of them completely, I will still explain it again.
Below we directly on the code:
1 static void Main (string[] args) 2 {3 Type t = typeof (Refclass); 4 Refclass RC = new Refclass (); 5 RC. TEST3 = 3; 6 methodinfo[] Finfos = t.getmethods (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Static); 7 foreach (MethodInfo finfo in Finfos) 8 {9 if (finfo. GetParameters (). Count () > 0 && finfo. GetParameters () [0]. ParameterType = = typeof (String)) Ten {one object obj = Finfo. Invoke (RC, new[] {"123"}), MethodBody mbody = Finfo. Getmethodbody (); Console.WriteLine ("Method name with parameter: {0} return value type: {1} parameter 1 type: {2} parameter 1 Name: {3}" value returned after method call: {4} ", 14 Finfo. name,15 Finfo. Returntype.tostring (), Finfo. GetParameters () [0]. Parametertype.tostring (), Finfo. GetpaRameters () [0]. name,18 obj. ToString ());}20 Else21 {methodbody mbody = Finfo . Getmethodbody (); Console.WriteLine ("Method name without parameters: {0} return value type: {1}", Finfo. name,25 Finfo. Returntype.tostring ());}27}28 Console.readkey (); 29}
Here I have made some simple judgments such as judging the number of input parameters and types, if you do not make these judgments will lead to the program can not continue to execute, specifically why to look at the results of the output, you can understand why I have to do so.
Here are the specific results:
The reader must have found that there are also get and set, and you might think that they are not attributes? How to run to the method here, in fact, I have said above. These are actually methods. This is why I need to determine the number of input parameters and the type of the above reasons.
Go C # 's Topsy-reflex