IL series of articles five:
Property in il
In C # Property is called a smart field, it is a very interesting thing. Why is it called a smart field? Because we can use it like the fields.
Let's take a look at C or other traditional object-oriented languages. In Class we will define some Data Field, we may need to access it in another class. But can you just declare it as public? The answer is definitely can't! We have to package it. In fact, the most common method is getter and setter, and make some necessary processes for us to read or set it to ensure the security of our Class. OK! Now C # appears, Property instead of getter and setter, its purpose is only more naturally in the user's user. Use a simple class member access method (Class.Datafield) than using a function to call more natural, and also hide some of the technical details of the background. But how is a simple access (Class.Property) produces a magical effect as a function call? Let me tell you, in fact it is a getter and setter. Do not believe? How does Property is a function? Well, let's take a look. Let's take an example first.
//Propertytest.cs
Using system;
Class Student
{
Protected int Age;
Public Int Age
{
get
{
Console.WriteLine ("I am in get");
Return Age;
}
set
{
Console.WriteLine ("I am in set");
Age = Value;
}
}
}
Class app
{
Public static void
Main
()
{
Student Windfast = New Student ();
Int myage;
WINDFAST.AGE = 21;
Myage = windfast.age;
}
}
This is a very simple example, there will be two lines of outputs running. There is still a strange thing I don't know if you noticed it? Is the value in Set, how did this value come out? Isn't it possible to use it first? Let's analyze it, or old way - anti-compilation. Below is its IL code. (I wrote such a short story, I feel more and more difficult to tell you, IL code is getting longer and longer. Everyone looks out - so long ?! May not be willing to look down. I think It's okay.)
.Assembly property {}
.CLASS Private Auto Ansi Beforefieldinit Student
Extends [mscorlib] system.Object
{
.field family int32 age // data field "agn"
.method public hidebysig specialname instance int32 // it's a method!
GET_AGE () CIL Managed // A getter, return int32
{
.MAXSTACK 1
.locals init (INT32 V_0)
LDSTR "I am in get"
Call void [mscorlib] system.console :: writeline (String)
Ldarg.0 // The ldarg.0 instruction loads The Method's first argument // (The Hidden this Pointer) ONTO The Stack.
LDFLD INT32 Student :: agnge
STLOC.0 // let the local variable equaled student :: agnge
Br.s IL_0013
IL_0013: ldloc.0 // load the return value ONTO THE STACK
RET
} // end of method student :: get_age
Public Hidebysig SpecialName Instance Void
Set_age (int32 'value') cil managed // there is parameter named 'Value'
{
.maxstack 2
LDSTR "I am in set"
Call void [mscorlib] system.console :: writeline (String)
ldarg.0
ldarg.1
Stfld Int32 Student :: Age // Student :: Age = VALUE
RET
} // end of method student :: set_age
Public Hidebysig SpecialName RTSpecialName
Instance void .ctor () Cil Managed // The Constructor of this class
{
.MAXSTACK 1
ldarg.0
Call instance void [mscorlib] system.Object ::. ctor ()
// Call the constructor of pent
RET
} // end of method student ::. ctor
.property instance int32 age () // The getter and setter are defined here
{
.get instance int32 student :: get_age () // be Care of the return TYPE
.set instance void student :: set_age (int32)
} // End of Property Studient :: agnge
} // End of class student
.CLASS Private Auto Ansi Beforefieldinit APP
Extends [mscorlib] system.Object
{
Public Hidebysig static void
Main
() CIL Managed
{
.entrypoint
.maxstack 2
.locals init (Class Student Windfast, INT32 Myage)
NEWOBJ Instance Void Student ::. ctor ()
STLOC Windfast // Student Windfast = New Student ();
LDLOC WINDFAST
ldc.i4.s 21
Callvirt Instance Void Student :: SET_AGE (INT32) // Call The Setter
LDLOC WINDFAST
Callvirt Instance Int32 Student :: get_age ()
STLOC Myage
RET
} // end of method app :: main
} // end of class app now believes, Property magical effect is actually the same as the traditional Getter and Setter. When we compile the C # program to IL, Property is compiled into a function that is prefixed in GET_ and SET_. At runtime IL is also the definition of GET and SET by calling these two. In this case, then we will call the windfast.get_age () in C #, you try ... this is impossible! Ha ha.
Everyone pays attention to the IL has such a code ".property instance int32 age () {...}", which is used to define Property. Since the C # is directly handled in the process of compilation, how do you want to define it? This is designed to be able to use Metadata to record information about Property, and you can get this information through REFLECTION.