CIL之——值类型与引用类型的声明和使用

在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()
        }
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

若恰好帮到您,请随心打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值