在C#代码中调用值类型的变量和调用引用类型的变量没什么区别,但是在CIL代码中就有不一样了,下面让我们看一下CIL代码是如何实现这一功能的吧!
C#目标代码
namespace ConsoleTest
{
public class Program
{
public static void Main(string[] args)
{
Person objPerson = new Person();
WorkExperience resume = objPerson.GetResume();
Console.WriteLine("timeArea:{0} company:{1}", resume.TimeArea, resume.Company);
int age = objPerson.GetAge();
Console.WriteLine("age:{0}", age);
Console.ReadKey();
}
}
public class Person
{
private string name;
private int age;
private WorkExperience workExperience;
public Person()
{
}
public Person(string name, int age, WorkExperience workExperience)
{
this.name = name;
this.age = age;
this.workExperience = workExperience;
}
public WorkExperience GetResume()
{
WorkExperience workExperience = new WorkExperience("2010-06-11", "BigData");
return workExperience;
}
public int GetAge()
{
int age = 12;
return age;
}
}
public class WorkExperience
{
public string TimeArea { get; set; }
public string Company { get; set; }
public WorkExperience()
{
}
public WorkExperience(string timeArea,string company)
{
this.TimeArea = timeArea;
this.Company = company;
}
}
}
对应CIL代码
.namespace ConsoleTest
{
.class public Program extends [mscorlib]System.Object
{
.method public void .ctor()
{
.maxstack 8
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
.method public static void Main(string[] args)
{
.entrypoint
.maxstack 3
.locals init(
//声明引用类型的局部变量必须加class关键字且类型必须使用类的全称
[0] class ConsoleTest.Person objPerson,
[1] class ConsoleTest.WorkExperience resume,
//声明值类型的局部变量直接使用类型即可
[2] int32 age
)
newobj instance void ConsoleTest.Person::.ctor()
stloc.0
ldloc.0
//返回值为引用类型时必须加class关键字且类型必须使用类的全称
call instance class ConsoleTest.WorkExperience ConsoleTest.Person::GetResume()
stloc.1
ldstr "timeArea:{0} company:{1}"
ldloc.1
//返回值为值类型时直接使用类型即可
call instance string ConsoleTest.WorkExperience::get_TimeArea()
ldloc.1
call instance string ConsoleTest.WorkExperience::get_Company()
call void [mscorlib]System.Console::WriteLine(string,object,object)
ldloc.0
call instance int32 ConsoleTest.Person::GetAge()
stloc.2
ldstr "age:{0}"
ldloc.2
box int32
call void [mscorlib]System.Console::WriteLine(string,object)
call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
pop
ret
}
}
.class public Person
{
.field private string name
//声明值类型的字段时直接使用类型即可
.field private string age
//声明引用类型的字段时必须加class关键字且类型必须使用类的全称
.field private class ConsoleTest.WorkExperience workExperience
.method public void .ctor()
{
.maxstack 1
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
//值类型的参数直接使用类型即可
//引用类型的参数必须加class关键字且类型必须使用类的全称
.method public void .ctor(string name,int32 age,class ConsoleTest.WorkExperience workExperience)
{
.maxstack 1
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ldarg.0
ldarg.1
stfld string ConsoleTest.Person::name
ldarg.0
ldarg.2
//对值类型的字段赋值时直接使用类型即可
stfld int32 ConsoleTest.Person::age
ldarg.0
ldarg.3
//对引用类型的字段赋值时必须加class关键字且类型必须使用类的全称
stfld class ConsoleTest.WorkExperience ConsoleTest.Person::workExperience
ret
}
//返回值为引用类型时必须加class关键字且类型必须使用类的全称
.method public class ConsoleTest.WorkExperience GetResume()
{
.maxstack 2
.locals init(
class ConsoleTest.WorkExperience workExperience
)
ldstr "2010-06-11"
ldstr "BigData"
newobj instance void ConsoleTest.WorkExperience::.ctor(string,string)
stloc.0
ldloc.0
ret
}
//返回值为值类型时直接使用类型即可
.method public int32 GetAge()
{
.maxstack 1
.locals init(
int32 age
)
ldc.i4 12
stloc.0
ldloc.0
ret
}
}
.class public WorkExperience
{
.field private string _timeArea
.field private string _company
.method public void .ctor()
{
.maxstack 1
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
.method public void .ctor(string timeArea,string company)
{
.maxstack 2
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ldarg.0
ldarg.1
call instance void ConsoleTest.WorkExperience::set_TimeArea(string)
ldarg.0
ldarg.2
call instance void ConsoleTest.WorkExperience::set_Company(string)
ret
}
.method public string get_Company()
{
.maxstack 1
.locals init(
string company
)
ldarg.0
ldfld string ConsoleTest.WorkExperience::_company
stloc.0
ldloc.0
ret
}
.method public void set_Company(string val)
{
.maxstack 1
ldarg.0
ldarg.1
stfld string ConsoleTest.WorkExperience::_company
ret
}
.method public string get_TimeArea()
{
.maxstack 1
.locals init(
string timeArea
)
ldarg.0
ldfld string ConsoleTest.WorkExperience::_timeArea
stloc.0
ldloc.0
ret
}
.method public void set_TimeArea(string val)
{
.maxstack 1
ldarg.0
ldarg.1
stfld string ConsoleTest.WorkExperience::_timeArea
ret
}
.property instance string Company()
{
.set instance void ConsoleTest.WorkExperience::set_Company(string)
.get instance string ConsoleTest.WorkExperience::get_Company()
}
.property instance string TimeArea()
{
.set instance void ConsoleTest.WorkExperience::set_TimeArea(string)
.get instance string ConsoleTest.WorkExperience::get_TimeArea()
}
}
}