The reflection of c #: Definitions YAOTIEBING reflected reflection Overview: review of metadata and gather information about the capabilities of its type. Metadata (the most basic data unit after compilation) is a large pile of tables. When compiling assemblies or modules, the compiler creates a class definition table, a field definition table, and a method definition form, etc. System.Reflection namespace contains several classes that allow you to reflect (pars) the code and reflection of these metadata tables (we are accessing reflection information through these namespace): System.Reflection.MemberInfo System. hierarchical model Reflection.EventInfo System.Reflection.FieldInfo System.Reflection.MethodBase System.Reflection.ConstructorInfo System.Reflection.MethodInfo System.Reflection.PropertyInfo System.Type System.Reflection.Assembly reflected: Note: inter are many levels The role of relational reflection: 1. You can use the reflexive dynamically created an instance of the type to bind the type to an existing object, or get the type 2 from the existing object. The application needs to load a specific type from a particular assembly at runtime to reflect a certain task. 3. Reflecting the main application and class library, these class libraries need to know a type of definition to provide more features. Application points: 1. There are very few applications that require reflex type 2 in real-world applications. Use the reflected dynamic binding to sacrifice performance 3. Some metadata information cannot be obtained by reflection 4. Some reflection types are specially used for the development of the CLR development compiler, so you have to realize that not all reflection types are suitable for everyone. The assembly reflects AppDomain When you need to reflect all the assemblies included in AppDomain, the example is as follows: static void main {// All assemblies of AppDomain via getassemblies FOREACH (askEMBLY Assem in Appdomain.currentDomain.getassemblies ()) {//// Reflecting the current assembly Information Reflector.ReflectonAssembly (Assem)}}}}}}}}} Note: The getassemblies method for calling the Appdomain object will return an array composed of System.Reflection.Assembly elements.
Reflecting a single assembly The above method is to reflect all the assemblies of AppDomain, and we can display an assembly in which the System.Reflecton.assembly type provides the following: 1. LOAD method: a method of high recommendation, the LOAD method with an assembly flag and load it, LOAD will cause the CLR to apply the policy to the assembly, and then in the global assembly buffer, application base catalog and private path The assembly below is found, if you can't find the assembly system throw an exception 2. LOADFROM method: Pass the path name (including extensions) of an assembly file, the CLR will load the assembly you specify, the parameter passed cannot contain any information, regionality, and public key information about the version number, if The assembly throw an exception in the specified path cannot be found. 3. LoadwithPartialName: Never use this method because the application cannot determine the version of the assembly that is loaded. The unique use of this method is to help customers who use the .NET framework in the .NET framework, this method will eventually be abandoned.
Note: System.Appdomain also provides a LOAD method, his and Assembly's static LOAD method is different, AppDomain's LOAD method is an instance method, returning a reference to the assembly, assembly's static LOAD party The assembly Press value package Send back to the called Appdomain. Try to avoid using the AppDomain's LOAD method using the reflection acquisition type information, the reflection of the assembly is complete, and the third level in the reflection hierarchy model is shown. Type reflection An example of a simple use of reflection acquisition type information: use system; useing sytem.reflection; class reflecting {static void main (string [] args) {reflecting reflect = new reflecting (); // Define a new self-class // calling a reflecting.exe assembly assembly myAssembly = assembly.loadfrom ( "reflecting.exe") reflect.getreflectioninfo (myAssembly); //} // acquires reflection information defines a method of acquiring content reflected void getreflectioninfo (assembly myassembly) {type [] TYPEARR = myassemby.gettypes (); // Get Type Foreach (Type Type "// Gets Details for Each Type {// Get Type Structure Information ConstructorInfo [] MyConstructors = type.getConstructors; // Get Type Field Information FieldInfo [] Myfields = Type.Getfiedls () // Get Method Information MethodInfo MymethodInfo = Type.getMethods (); // Get Properties Information ProPE RTYINFO [] MyProperties = type.getProperties // Get event information Eventinfo [] myevents = type.getevents;}}} Other methods of obtaining Type objects: 1. The System.Type parameter is a string type, which must specify the full name of the type (including its namespace) 2. System.Type provides two instance methods: GetNestedType, GetNestedTypes 3. The instance method provided by the Syetem.Reflection.AssEMBLY type is: gettype, gettypes, getExporedTypes 4. System.Reflection.moudle provides these instance methods: GetType, GetTypes, FindTypes Settings a member of the reflective type of reflection type is the bottom layer of data in the reflection hierarchy model. We can get a type of member through the GetMembers method of the Type object.
If we use a GetMembers without parameters, it only returns a static variable and instance member of this type of public definition, and we can also return to the specified type member by using the parameter-based getMembers. Detailed description of the type of System.Reflection.BindingFlags in MSDN. For example: // Set members need to return a type of content bindingFlags bf = bingdingFlags.DeclaredOnly | bingdingFlags.Nonpublic | BingdingFlags.Public; foreach (MemberInfo mi int t.getmembers (bf)) {writeline (mi.membertype) // output specification Type Members} By reflection creation type, you can get the type of assembly by reflection, we can create this type of instance based on the acquired assembly type, which is also the previously mentioned to create objects to achieve evening tie The function we can implement: 1 by the following methods: 1. System.actiVator's CreateInstance method. This method returns a reference to the new object. See MSND 2 for specific usage. System.Activator's CreateInstanceFrom is similar to the previous method, but you need to specify the type and its assembly 3. System.Appdomain's Method: CreateInstance, CreateInstanceAndunwrap, CreateInstranceFrom, and CreateInstraceFromandUnwrap 4. System.Type's InvokeMember instance method: This method returns a constructor that is consistent with the incoming parameters and constructs this type. 5. System.Reflection.constructInfo's Invoke instance method Reflecting type interface If you want to get all interface collections inherited, you can call Type's FindInterfaces GetInterface or GetInterfaces. All of these methods can only return the interface directly inherited, they don't return the interface that inherits from an interface. The basic interface to return the interface must be called again. Reflection performance: Use reflection to call types or trigger methods, or when accessing a field or attribute, the CLR needs to do more work: check parameters, check permissions, etc., so speed is very slow. So do not use the reflection to program, for the application of a dynamic constructive type (evening binding), you can take the following ways instead: 1. Through the inheritance relationship of the class. Let this type derive from a compile-known basic type, generate an instance of this type of schema at runtime, which will be placed in a variable of its base type, then call the basic type of virtual method. 2. Implemented through the interface. At runtime, a instance of this type is built, and the reference will be placed in a variable of its interface type, then call the imaginary method defined by the interface. 3. By delegate implementation. Let this type implement a method, its name and prototype are compliant with a known entrustion when compiling. The instance of this type is constructed at runtime, and then constructs an instance of the delegate with the object and name of this method, then the method you want by delegate. This method is more than working with the previous two methods, and the efficiency is lower, and more dynamic call code.
Last time I saw a comparison of dynamically calling code, the example used in the MSDN website appeared to be more complicated. To calculate a complex multi-item child, partially cut it, dynamically form code segment to be circulated. Detailed view. Several dynamic generating code patterns in .NET comparison. Today, I saw another comparative article written by Microsoft C # team, in order to illustrate the performance and calculation accuracy, reduce the impact of compilation and optimization due to complex function, he uses an extremely simple Example: Enter a parameter, then return this parameter to add one, such a simple function, optimization, and unopened code should not have a difference. public
Class
PROCESSOR
{Public int process (int value) {returnavalue 1;}}
In contrast, in addition to the last few, it also added a proxy mode call to compare. Direct call
int
Value
=
Processor.Process (i);
2. Type.invokemember () calls with reflective mechanisms.
Type T
=
Typeof
(Processor);
int
Value
=
(
int
) T.Invokemember
"
PROCESS
"
BindingFlags.instance
|
Bindingflags.public
|
BindingFlags.InvokeMethod,
NULL
, Processor,
New
Object
[]
{i}
);
3. Through an interface
public
Interface
IProcessor
{INT Process (int value);
4. Through a commissioned delegate
public
Delegate
int
ProcessCaller
int
Value; ProcessCaller ProcessCaller
=
New
ProcessCaller (Processor.Process);
int
Value
=
ProcessCaller (i);
5. Establish a commissioned re-dynamic call by reflex mechanism
Type delegateType
=
CreateCustomDelegate (MethodInfo); DELEGATE P
=
Delegate.createDelegate (delegateType, Process,
"
PROCESS
"
);
int
Value
=
(
int
P. DynamicInvoke
New
Object
[]
{i}
);
6. Milled mode
For 2 and 5, due to the use of reflective mechanisms, it is not possible to establish an intermediate temporary object to deliver parameters, and the parameters and return values, etc., therefore spend a lot of machine time.
Below is a result of the run (100,000 times in loop):
Conclusion: 1. Direct calls are the fastest. 2. The interface call is fast programming, and the meta-programming is faster than the entrustment method, but Microsoft believes whidbey will greatly optimize the principal-calling mode, so that it approaches the level of interface calls. 3. Directly use Type's reflex mechanism is the slowest speed, and it is slow to dynamically call to the reflex mechanism. 4. Direct use delegate is not flexible, sometimes it needs to be invoked with reflex mechanisms, but will reduce performance. It is desirable that WHIDBey can improve the performance of the entrusted performance, and flexibility is to sacrifice performance. Code
CN.Text development notes - use reflection to read data into physical classes
In actual development, we often need to read data from the database and assign a respective attribute to the entity class. There is a large amount of such code in the DataDtoprovider of .Text, such as:
public
Role [] getRoles
int
BlogID)
{System.Collections.ArrayList Al = new system.collections.arraylist (); idatarader reader = dbProvider.instance (); getroles (blogID); try {whele ()) {role = new role (); IF (Reader ["RoleID"]! = dbnull.value) {role.roleid = (int) reader ["roleid"];} if (Reader ["name"]! = dbnull.value) {role.name = String) Reader ["Name"];} if (Reader ["Description"]! = dbnull.value) {Role.description = (String) Reader ["Description"];} // readertoObject (Reader, Role); Al .Add (role);} finally {reader.close ();} return (role []) al.toArray (TypeOf (roule); }
For the above code, I think there is a few things: 1. Each time I assign the value of the Role, I have to check if the value of Reader is DBNULL, and there are many duplicate code 2, each time the property of Role When you assign a value, you must perform type conversion, and the type of the role property is known, is it possible to automate this conversion? 3. Each time you assign the property of the Role, the role properties are performed with the database field. If we are designing the database and entity class, ensure that the database field is the same name and the physical class property, the use of reflection, we can automatically perform the property and field by code. Even if the database field is different from the attribute, we can also do this by changing the query statement. Is it possible to improve the code above, making the code more elegant? What should the elegant code? If we use the code line readertoObject (Reader, Role) that comments in the above code; replacing it before The Role property is assigned statement. Is it possible to make the code more elegant? The role of ReadertoObject is to automatically complete the value of the value in the READER in the Role (provided the field in the reader and the corresponding attribute in the Role) Has the same name). Now our task is to achieve readertoObject. With a powerful weapon -Reflection, our task has become very relaxed, not to say, the following code is my implementation method: private
Void
ReadertoObject (iDataReader Reader,
Object
TargetObj)
{For (int I = 0; i ReadertoObject can read the data in the Reader into any entity class. The data library field is the same as the mapping principle of the physical class properties. Of course, we can also make both mappings through the configuration file. Personal Idea: In the development, facing so many design ideas and design patterns, often confused, when you put more energy in which design idea or design pattern, I don't want to ignore it is very important. Reduce the repeated code as much as possible, as long as we can effectively reduce duplicate code, the method we use is a good way, instead careful of which mode. Just like a solitary sword, it is because of the binding of the traditional move, it will be uncomfortable! .NET Quick Tip: Runtime Type Conversion for Enumeration Let's first look at this NUnit test code, we want to use the reflex mechanism to access an object's enumeration type domain or property: [TestFixture] public class PaymentInfo {public enum PaymentType {Cash, CreditCard, Check} public PaymentType Type; public void Test () {PaymentInfo payment = new PaymentInfo (); payment.Type = PaymentType.Cash; System.Reflection.FieldInfo enumField = . GetType () GetField ( "Type"); int paymentTypeInt32; paymentTypeInt32 = (int) enumField.GetValue (payment); Assert.AreEqual ((int) PaymentType.Cash, paymentTypeInt32); enumField.SetValue (payment, paymentTypeInt32); Assert .Arequal (paymenttype.cash, payment.type);} I found an exception on this line of the red: "The object type cannot be converted to the target type". The reason is that it is because the reflection mechanism of the CLR does not allow implicit conversion between the enumeration type and integer type. However, the C # compiler or allows us to perform explicit conversions between the two through the syntax of the mandatory type. In this test, it is actually very simple in this test: the scribe portion is forced to convert to an enumeration type, such as: (paymenttype) PaymentTypeInt32. The problem is: How do you dynamically convert the type during runtime? For example, when I am writing Elegantdal, I need to write a type of type INT from the database to INT to an enumeration field of the object you want to return. At this time, I only have FieldInfo, ColumnValue and ResultObject, but write into FieldInfo. .SetValue (ResultObject, ColumnValue) will appear the previously mentioned error, but I only have a running type information (FieldInfo.fieldType), I can't write into FieldInfo.SetValue (ResultObject, (FieldInfo.fieldType) ColumnValue ... ... I have to list this as a special case, and our salvage is an enum.TOOBJECT () method - Do you know if there is a better way to solve this problem?