Statement
This article welcome reprint , original address:http://www.cnblogs.com/DjlNet/p/7192354.html
Objective
About this book ("in-depth understanding of the third edition of C #") details and good or bad, self-search can be, I'm not the wordy, this ads in the backup, is intended to record the second reading found in the original swallowed, but also in order to remember deeply. There's also a copy of the CLR via C # Fourth edition is also ready to read two times, about precision reading chapters, know the portal (Zhao brother-in-law answer): https://www.zhihu.com/question/27283360. Just yesterday (September 9) Beijing and Shanghai have launched a technology sharing meeting (there is a synchronous live), here to give the Beijing SQL Server address of the elder brother praise, speak well to the ground and real, as well as Shanghai's shared ". Net micro-service combat", to see the heart is very touching, is not to say from the level of knowledge or practice to comprehend how many, but understand and understand why this thing is born, cultivate a little bigger picture and thinking routines, after all, in the DDD, micro-services in the way of today only continue to learn, and then warm so that the new, may be able to know what they want to express the meaning of it!
Do you remember this knowledge,
\ (^∀^) belongs
The above pulled some saliva words, in fact, in learning the knowledge of the structure, then the only way is to grasp the basic language and understanding of the upper frame, then today to pull the framework and frame to review some of the knowledge of the language, the following is recorded in some of the books in the search for leaks from the personal backup memory use , which may also contain the following less common or small knowledge, big God Big Brother please automatically ignore, haha.
Myth: Objects are passed by reference by default in C #
I quote some of the quotes from the book: first, the formal definition of "citation transfer" is quite complex, involving Lvalue and similar computer science terminology, but most importantly, if you pass a variable in a reference-passing way, The called method can change the value of the caller's variable by changing its parameter value (when it comes to the idea that the ref out keyword is in the wood, they can achieve the effect of the reference pass). So by default, if the use of keywords is not shown, the value of the reference type variable is a reference (like this: 0x12345678), rather than the object itself, and does not need to pass the parameter by reference itself, you can change the contents of the object referenced by the parameter. For example: The following method changes the contents of the related object StringBuilder, but the caller's expression refers to the previous object:
void AppendHello(StringBuilder builder){ builder.Append("Hello");}
When this method is called, the value of the parameter (a reference to StringBuilder) is passed in the way that the value is passed . If you want to change the value of a builder's variable inside a method, such as: builder=null;
It is invisible to the caller.
Understanding: How the JIT compiler handles generics
For all enclosing types, the JIT's duty is to convert the Il of the generic type to local code, and we take the list as an example, first, JIT creates different code for each enclosing type that takes a value type as a type argument, theoretically, for some value types, the code can be shared, But the JIT must be very cautious, not only to consider the problem of space size, but also to consider the problem of garbage collection, so the first time to create exclusive code. So, all enclosing types that use reference types (string, stream, StringBuilder, and so on) as type arguments share the same native code, and this is possible because all references have the same size (4 bytes on 32-bit CLR). The 64-bit CLR is 8 bytes, and all references in any particular CLR have the same size). With regard to the new API for generics,GetGenericTypeDefinition works with the constructed type, gets its generic type definition, and markgenerictype the definition of the generic type, returns a constructed type, And so on:getgenericarguments, IsGenericTypeDefinition, Isgenerictype, Markgenericmethod, Isgenericmethod and so on.
Nullable type understanding and using Null for assignment and comparison principles
Note that nullable is a struct, which is a value type , and for variables such as nullable, directly contains a bool and an int member instead of a reference to another object. About null assignment comparisons, principle: The C # compiler allows Nulls to be used to represent null values for a nullable type when comparing and assigning values. One of the reasons for dealing with this is that it is also the same experience of making semantics more consistent with natural logic from the language level and getting and referencing the type null. So what exactly does the compiler do for us with regard to nullable value types, int? a=null; if(a==null){ .... }
which, in fact, are converted to calls in the compiler-generated IL code, to a null for a, and actually to a a.HasValue
constructor that calls nullable to create a null instance, pay attention to calling a directly . Value throws an exception if no real value is provided.
Note Anonymous function variable capture
Focus: 1, the capture is the variable itself, instead of creating a delegate instance its value 2, the lifetime of the captured variable is extended, at least as long as the delegate that captures it 3, multiple delegates can catch the same variable 4, within the loop, the same variable declaration actually refers to a different variable "instance" (this point in the r# will also prompt the developer) 5, if the captured variable does not change, there is no need to worry about 6, c#5 or above to correct the meaning of the foreach, but for still need attention.
Understand yield's workflow and become the cornerstone of design that lays out asynchronous async/await
The code in the book is directly referenced to enhance memory and familiarize yourself with the next process, as shown in the code: about the execution process of code that has to look at itself, slowly follow the execution process, I believe you can understand the role of Yield in code execution, it seems to be able to jump between different methods , in general, can be classified as a few points: 1, before the first call to MoveNext, the code in Createenumerable will not be called 2, all the work is done at the call to MoveNext, the value of getting current will not execute any code 3, In the position of yield return, the code stops execution, the method temporarily returns the caller method, and the next execution of MoveNext continues on the next line of code 4, in a method at different locations can write multiple yield return statement 5, The code does not end at the last yield return but ends the execution of the method by returning a MoveNext call to false. so much is said on the 3rd and 4 points that there is no sense that the part of the await function is familiar, Await can also allow the method to return and wait there until the result is received and then the "breakpoint" continues to execute, and in an async-tagged async method, there are multiple await the unpacking operation, so to a certain extent above yield on the thought and design level, to the back of C # 5 of the asynchronous buried the foreshadowing. From the state machine point of view (this piece is not very familiar, so wrong, please treatise) the similarity between the state machines generated for the iterator block in c#5 and those of the asynchronous functions is astonishing. The two complex problems in asynchronous development are: 1, processing State 2, effectively pausing before the event of interest occurs, and the iterator makes the two problems perfectly solved. here is the pseudo-code for yield implementation async, and also the code snippet in the book: (Pseudo-code is implemented based on CCR, the main thing is to understand that it wants to convey the meaning of the expression, you can see the Code section is good)
Static ienumerator<itask> Computetotalstockval. (Str.user,str.pass) {String token=Nullyield return arbiter.receive ( False,authservice.ccrcheck (User,pass), delegate (string t) { token=t; }); ienumerablenull; Idictionary<string,decimal> rates= null; yield return arbiter.joindreceive ( false, dbservice.ccrgetstockholdings (token), stockservice.ccrgetrate (token), delegate (ienumerablestring,< Span class= "Hljs-keyword" >decimal> R) {stocks=s; rates=r;}); Onrequestcomplete (Computetotal (stocks,rates));
Basically explain the above code, although it is pseudo-code, CCR calls our code called MoveNext, the first yield return will execute, Authservice inside the Ccrcheck method to initiate an asynchronous request, CCR waits until it is done, and then gives it a delegate to handle the resulting result, which is token, and then calls MoveNext again, then executes, Joindreceive initiates two asynchronous requests in parallel, and uses subsequent delegates to process the results when all two requests are completed. , after which MoveNext is called again, all requests are processed.
Small summary
Back to see some basic knowledge, only to find that the original language level design is not more important than some high-level architecture design and ornamental poor (although there is nothing comparable, haha), well, it is not early, the following should be a sequel, and so after this is over, it should start on some of the points of concern, down from the code, Requirements and design level consider to write some code snippets or programs that can be used for future reference or reference. At the end of the day, give yourself a slap on the face, I am really lazy, to see how long from the last posting, give their words: from now on do a not so lazy people! I remember!!!
"C # in depth third edition" new (1) (EXT)