[Reading Notes] two interesting knowledge points in the Framework Design (version 2nd) CLR via C # (good)

Source: Internet
Author: User

From: http://www.cnblogs.com/Thriving-Country/archive/2009/12/20/1628314.html

This quarter, the company asked to read the book "Framework Design (version 2nd) CLR via C #", because the previous two months have been very busy and have no time to read, occasionally reading is also very late when you go home before going to bed to pick up this classic reading such a section. I was deeply touched by the recent weekend. I have read the first version of this book before 《. net Framework Design, at that time, I especially admired uncle Jr's technical skills and writing skills. As someone commented in the book, Jr is indeed suitable to describe the concept of being difficult to understand in a short language. In addition, the "Windows core programming" to be read in the next quarter is more of a classic (I have read this book). There is no doubt about the classics. Here I just want to express my feelings, I believe that people who have read these two books have such feelings. I think these two books should be purchased and read by a Windows programmer and put in the case favorites.

When I read this book, I found a lot of interesting things worth thinking about, such as Jr's suggestions on calling parameters and returned values, bit indexer examples, and event triggering security; format strings and resident strings. Especially. Net's garbage collection mechanism is detailed in this book. There are two knowledge points that make me feel a lot of GAINS and the examples are also very detailed. Here I will share them with you separately, and I will also summarize them as knowledge points, there is no technical content here. Don't BS me.

  Part 1: Differences and comparison between constants, read-only fields, static fields, and static read-only fields

  ConstantA constant is a symbol that never changes. net After compilation, the constant value will be inserted into the Assembly metadata, so the constant type must be. net primitive types: Boolean, Char, byte, sbyte, int16, int32, uint32, int64, uint64, Singe, double, decimal, and string. That is to say, define a constant in the class of Assembly A and use this constant in assembly B. After the two assembly are compiled, C # The Compiler inserts this constant into the metadata of assembly B using this constant. In this case, assembly a using the constant has no runtime dependency on assembly B defining the constant, that is to say, you can delete assembly a that defines constants at runtime, it also indicates that if you modify the value of this constant and then compile the Assembly a that defines the constant, it will not change the value of this constant obtained by assembly B that uses the constant at runtime, constants bring this benefit, while obviously it is very unfavorable for the assembly version control. If an assembly needs to always obtain the latest data from another assembly, constants are not allowed. In this case, read-only fields can be used. In addition, constants have the meaning of static. They can only be accessed by type and cannot be accessed by objects.

  Read-Only Field: The read-only field is also a field that cannot be modified during verification after initialization (this initialization is initiated at the beginning of the runtime). the read-only field can reference any type of object. However, note that only the read-only field can assign a value to this field during object initialization, that is, the field also has writable attributes during initialization, and this field will be read-only in the future, the field read-only means that the reference of this variable cannot be changed, but the status of the referenced object can be changed. The compiler and verification mechanism ensure that the read-only field is not written by any other method, but we can still use reflection to modify the read-only field. The read-only field belongs to the object instance and needs to be accessed through the object. It is part of the object state.

  Static Field: The static field is a member associated with the type (only access by type is allowed. Unlike Java, the static field can be accessed through the class instance, if you remember correctly ), static Field Initialization is performed when the type is loaded into CLR. Static fields can apply any type of objects.

  Static read-only Field: Static read-only fields are similar to constants, but static read-only fields are not limited to primitive types. They can be. for any type in. net, static read-only fields, unlike constants, are inserted into metadata during compilation, while static read-only fields are assigned and determined at runtime, that is to say, the dependency on the program is a strong dependency. The specific value is obtained from the program in the runtime, rather than being a constant for copying and inserting metadata. Static read-only fields belong to the type and are accessed by type.

Modify private fields through reflection. The following example uses reflection to modify private general fields, constants, read-only fields, static fields, and static read-only fields and print the results. Here, we can see that reflection is very powerful. Since private read-only fields can be modified, but note that constants cannot be modified through reflection, an error will be reported when the changes are made, this is related to the constant storage method. Reflection gives you the illusion that verification rules can be skipped. Sample Code:

Modifying private fields through reflection

Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. reflection;

Namespace falseverification
{
Class Program
{
Static void main (string [] ARGs)
{
Type type = typeof (sometype );

Sometype ST = new sometype ();
St. Print ();

// Normal field, of course, can be modified
Fieldinfo Fi = type. getfield ("f1", bindingflags. nonpublic | bindingflags. instance );
Fi. setvalue (St, (int32) Fi. getvalue (ST) + 1 );

// Constant field and reflection cannot be modified. If you cancel the annotation of the following statement, an error will occur during execution.
/* Cause Description: The constant value must be determined at compilation (only primitive type), that is, the value is assigned during definition.
The value of the compiled constant is stored in the Assembly metadata and cannot be modified during runtime;
Other fields are stored in the dynamic memory and can be modified at runtime. */
FI = type. getfield ("F2", bindingflags. nonpublic | bindingflags. Static | bindingflags. instance );
// Fi. setvalue (null, (int32) Fi. getvalue (null) + 1 );

// Read-only field, which can be modified through reflection
FI = type. getfield ("F3", bindingflags. nonpublic | bindingflags. instance );
Fi. setvalue (St, (int32) Fi. getvalue (ST) + 1 );

// Static field, which can also be modified
FI = type. getfield ("F4", bindingflags. nonpublic | bindingflags. Static );
Fi. setvalue (null, (int32) Fi. getvalue (null) + 1 );

// Static read-only field. The following code does not make an error and changes the value of the reflected field. However, the field value in the class is not changed.
FI = type. getfield ("F5", bindingflags. nonpublic | bindingflags. Static );
Fi. setvalue (null, (int32) Fi. getvalue (null) + 1 );
Int32 F5 = (int32) Fi. getvalue (null); // The I5 value is 51.

St. Print ();
Console. writeline ("F5:" + f5.tostring ());
Console. readkey ();
}
}

Public class sometype
{
Private int32 F1 = 30; // Private Field
Private const int32 F2 = 10; // Private constant Field
Private readonly int32 F3 = 20; // Private read-only Field
Private Static int32 F4 = 40; // Private Static Field
Private Static readonly int32 F5 = 50; // Private Static read-only Field

Public void print ()
{
Console. writeline ("F1:" + f1.tostring ());
Console. writeline ("F2:" + f2.tostring ());
Console. writeline ("F3:" + f3.tostring ());
Console. writeline ("F4:" + sometype. f4.tostring ());
Console. writeline ("F5:" + sometype. f5.tostring ());

Console. writeline ();
}
}
}

Running result:

From this result, we can see that through reflection, we can modify private common fields, read-only fields, static fields, and modification of these three fields are all correct, but constant fields cannot be modified. When a static read-only field is modified through reflection (similar to a constant), it can be executed normally, but the static read-only field obtained through the class has not changed, indicating that the modification was not successful, we actually modified the static read-only fields obtained through reflection and did not actually map them back. If you are interested in the specific cause, you can analyze it through Il.

  Part 2: gcbeep example in GC

First look at the Code:

Gcbeep

Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;

Namespace gcbeep
{
Class Program
{
Static void main (string [] ARGs)
{
New gcbeep ();

// Create many objects for GC to perform garbage collection
For (int32 x = 0; x <10000; X ++)
{
Console. writeline (X );
Byte [] B = new byte [100];
}
}
}

Internal sealed class gcbeep
{
/*
This is a Finalize method. GC finds the root
When gcbeep object is not referenced in
This method is called during garbage collection.
*/
~ Gcbeep ()
{
Console. Beep (); // Let the console send an alarm

If (! Appdomain. currentdomain. isfinalizingforunload ()&&! Environment. hasshutdownstarted)
{
// If a new gcbeep object is created without a variable when it is not uninstalled in the application domain or closed by the application itself
New gcbeep ();
}
}
}
}

During garbage collection, GC executes the Finalize method of the object to release unmanaged resources ~ Gcbeep (), In ~ The gcbeep () method first sends an alarm to the console, and then creates a gcbeep object without uninstalling the application domain or actively exiting the application, so that no variable can reference it, at this point, this object has actually become the target for the next GC garbage collection. The main function also creates a gcbeep object without variable reference as the entry point of the program, and then creates a large number of objects, when the related memory of the managed heap is used up, the garbage collection will be executed to recycle the garbage and release the memory to accommodate newly created objects. In this case, the garbage collection call ~ Gcbeep () sends an alarm. Create 10000 byte [] B = new byte [100]; send two alarms on my x86 win7 notebook. You can modify 10000 to a larger test, to determine the execution according to the alarm sound ~ The number of gcbeep () times.

In this example, I think the design is exquisite and concise, more importantly, it indicates that the Finalize method of the object is automatically executed during garbage collection to release the unmanaged resources (as an example, the actual release of the unmanaged resources is not done here ).

 

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.