Questions about the assignment of fields, properties, and constructors in C #
First, several questions are raised:
1, how to achieve their own injection framework?
2. What is the difference between a field and an automatic attribute?
3. What is the difference between a direct assignment and a constructor assignment when a field and an automatic attribute declaration?
4. Why are read-only fields and read-only automatic attributes (only get without a set accessor) assignable in the constructor?
5. Can reflection be assigned to a read-only or read-only property?
6. What is the difference between an automatic attribute and a normal attribute?
These are the questions I have when I try to write my own injection implementation. These questions should be learned in the first lesson of C #, and I see someone on the internet saying that he met an interviewer in an interview asking why read-only and read-only automatic attributes can be assigned in a constructor, he did not answer, and then he wrote the article to explore the problem, but did not come up with a clear answer, it is a pity. on-line about read-only properties some are write readonly features, read these articles directly skip it , the old version of C # now look no help.
Give the answer.
2, the attribute is more than the field get/set accessor, the field is a memory space declared in memory, you can actually store the value, the property is used as a field, but can have its own code snippet, can be assigned value, because the Access property is called property is get/ The Set method assigns a value to the field (or does not manipulate the field); on MSDN, it is recommended that the field be decorated as a private variable of the class using the private/protected adornment, and that the property is often used as a common property, and that the field reads and operates directly into the memory. The Get/set property is called by the accessor, so the field is faster than the property .
3, accurate, no difference. The difference is only the direct assignment performed first, and the constructor is assigned. In the generated IL intermediate language (C # code is first compiled into IL code and then compiled into assembly language), the field direct assignment and constructor assignment are in the same Code snippet (constructor).
4, the question can be combined with the above questions to answer. Constructors are the first to be accessed as an instance of a class's entry. The direct assignment of a field is actually performed in the constructor, so there is no difference between the direct assignment and the constructor assignment. The "Read only" limit is only maintained by the C # compiler (CLR), and I think the full name should be called "read-only in addition to the constructor" more accurately, which is the rule of C # syntax remember on the line (which is of course, the direct assignment is actually assigned in the constructor, If the constructor cannot be assigned a value, the read-only field has no value and is not declared.
5, the question can be connected with the above questions to answer together. Reflection allows you to assign values to a self-read field but cannot assign a value to a read-only property (you can try it if you don't believe it). The value of a read-only field is assigned because it bypasses the read-only display of the C # compiler (CLR), assigns a value to a read-only property, or calls the set accessor to assign a value to the field, because there is no set accessor so the error is allowed. So the question is, so why read-only automatic properties without a set accessor, you can also assign a value to a constructor function? in fact, the read-only automatic attribute is assigned in the constructor, essentially assigning a value to the field, and it has no relation to the get/set accessor of the property.
6 . What is the difference? Automatic attributes are always emphasized because automatic attributes are different from normal properties, such as read-only normal properties (no set accessors) that cannot be assigned in constructors. Before an automatic attribute is used, the normal property use step is to first declare a field such as _id, then declare a property ID, and do some operations in the get and set accessors, most of which are operations on field _id, but sometimes not related to fields. Normal properties can be passed "." Like a field. , but has a code snippet like a method (the normal attribute never opens up memory space ).
However, after c#3.0, an automatic attribute was introduced, declared as public int ID {get; set;},c#6.0 followed by public string FirstName {get; set;} = "Jane". Automatic attributes certainly open up memory space and then have the direct assignment of automatic attributes. In fact, declaring an automatic property in a class declares a hidden field in an intermediate language that is compiled into Il , then generates the Get/set method of the hidden field, and then generates the Get/set accessor . Here you can explain why read-only normal properties cannot be assigned (and directly assigned) in constructors, and read-only automatic attributes can be assigned (and directly assigned) in constructors, because the constructor in the generated IL code, whether directly assigned or assigned in the constructor, is the hidden field. Does not have access to the property's set accessor. (Note that this is just the automatic attribute in the class, the interface can have automatic attributes, but the automatic properties of the interface do not generate a hidden field but simply define the get/set accessor)
start explaining
Il intermediate language code generated by C # can be known more clearly
Public class User { publicint0; Public int Get Set 1 ; Public User () { 2; 3 ; } }
As you can see, the automatic properties generate a hidden private field named ' <age>k__backingfield ' + Private field Get/set method + attribute code snippet;
You can see that the IL code generates the user's constructor . ctor, ctor is a constructor (Constructor).
whether a direct assignment or a constructor assignment is performed in. ctor, and the action is a field, the assignment of an automatic property is a hidden field .
Public Interface Iuser { intgetset;} }
As you can see, the automatic properties in the interface do not generate hidden fields .
Other Notes
1. As mentioned above, " reflection can be assigned to a read-only field but cannot be assigned to a read-only property ." The read-only attribute cannot be assigned because there is no set accessor. But we already know that you can assign a value to a field, and that a read-only property generates a hidden field, is it possible to assign a value to an automatic property indirectly by assigning it to a hidden field? the answer is YES!
To define a read-only automatic attribute for user
Public class User { publicintget; 1 ; Public User () { 3; } }
Reflection Assignment code for the console:
varuser =NewUser (); Try{typeof(User). GetProperty (" Age"). SetValue (User,9); } Catch{Console.WriteLine ("read-only property assignment failed");} typeof(User). GetField ("<age>k__backingfield", BindingFlags.Instance | BindingFlags.NonPublic). SetValue (User,9); Console.WriteLine (User.age); Console.read ();
Run
2. Because the hidden field is private, it takes bindingflags.nonpublic to take the hidden field
3. Read-only automatic attribute description you don't want to be accessed. Why do you assign it to a value? This question ... I don't think there's anything I can do to play.
Related to field, property, read-only, constructor assignment, reflection assignment in C #