.net知识和学习方法系列(十八)CLR-构造函数

本文详细解析了构造函数的概念及其使用方式,包括实例构造函数与静态构造函数的区别,如何通过实例构造函数减少代码重复,以及静态构造函数的应用场景。
构造函数也叫构造方法,是一个比较特殊的函数,因为它没有返加回值,并且名称与所在类的类名相同。
构造函数有两种,一种是实例构造函数,一种是静态构造函数。
现有一个类:
    class Test
    {    
}
这个类与下面的类完全等价
    class Test
    {
        static Test()
        {
        }
        public Test()
        {
        }   
 }
也就是说,如果定义完一个类后,IDE会自动在类的内部定义一个实例化函数的。
如果在类中有字段的初始化,表态构造函数也会默认在类中,因为静态字段的初始化是在静态构造函数中实现的.
这两个构造函数是有区别,如果类中有静态构造函数,静态构造函数只在该类的第一个对象被实例化或有静态成员被调用时才调用,而实例化构造函数,则是在每次对象被实例化时调用。
实例构造函数可以有多个,通过参数来区分,或者参数的个数不同,或者参数的类型不能,也就是所谓的重载。但静态构造函数则有且只能有一个,并且不能有任何参数。
 
下面再看一下这个例子
class Test
{
        int a=1, b=2, c=3;
        int d;
        public Test()
        {
        }
        public Test(int i)
        {
        }
        public Test(string s)
        {
        }  
}
表面上看来没有什么,就是一个类中有三个构造函数,还有三个字段。
现在让我们看看IL吧
首先看一下这个类的IL
其中三个.ctor就是三个实例构造函数,双击三个构造函数来看一下它的IL代码:
Test()→.ctor:void()
.method public hidebysig specialname rtspecialname
        instance void .ctor() cil managed
{
 // 代码大小       31 (0x1f)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: ldc.i4.1
 IL_0002: stfld      int32 ConsoleApplication1.Test::a
 IL_0007: ldarg.0
 IL_0008: ldc.i4.2
 IL_0009: stfld      int32 ConsoleApplication1.Test::b
 IL_000e: ldarg.0
 IL_000f: ldc.i4.3
 IL_0010: stfld     int32 ConsoleApplication1.Test::c
 IL_0015: ldarg.0
 IL_0016: call       instance void [mscorlib]System.Object::.ctor()
 IL_001b: nop
 IL_001c: nop
 IL_001d: nop
 IL_001e: ret
} // end of method Test::.ctor
Test(int i)→.ctor:void(int32)
.method public hidebysig specialname rtspecialname
        instance void .ctor(int32 i) cil managed
{
 // 代码大小       31 (0x1f)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: ldc.i4.1
 IL_0002: stfld      int32 ConsoleApplication1.Test::a
 IL_0007: ldarg.0
 IL_0008: ldc.i4.2
 IL_0009: stfld      int32 ConsoleApplication1.Test::b
 IL_000e: ldarg.0
 IL_000f: ldc.i4.3
 IL_0010: stfld      int32 ConsoleApplication1.Test::c
 IL_0015: ldarg.0
 IL_0016: call       instance void [mscorlib]System.Object::.ctor()
 IL_001b: nop
 IL_001c: nop
 IL_001d: nop
 IL_001e: ret
} // end of method Test::.ctor
Test(string s)→.ctor:void(string)
.method public hidebysig specialname rtspecialname
        instance void .ctor(string s) cil managed
{
 // 代码大小       31 (0x1f)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: ldc.i4.1
 IL_0002: stfld      int32 ConsoleApplication1.Test::a
 IL_0007: ldarg.0
 IL_0008: ldc.i4.2
 IL_0009: stfld      int32 ConsoleApplication1.Test::b
 IL_000e: ldarg.0
 IL_000f: ldc.i4.3
 IL_0010: stfld      int32 ConsoleApplication1.Test::c
 IL_0015: ldarg.0
 IL_0016: call       instance void [mscorlib]System.Object::.ctor()
 IL_001b: nop
 IL_001c: nop
 IL_001d: nop
 IL_001e: ret
} // end of method Test::.ctor
 
很明显的看到三个实例构造函数都对a,b,c进行了初始化赋值即造成了代码的重复。
如果初始化的字段更多,构造函数更多,重复量就更大。
但值的注意的是,在Test类中有一个字段d,没有初始化,并且在所有的构造函数中也没有发现它,这个,就给我们避免代码重复提供了一个方法。
改造一下上面的代码:
class Test
    {
        int a,b,c;
        int d;
        public Test()
        {
            a = 1;
            b = 2;
            c = 3;
        }
        public Test(int i):this()
        {
        }
        public Test(string s):this()
        {
        }
    }
就在类中,先不去初始化字段,只在没有参数的实例构造函数中初始化,用其他构造函数来调用它,现在来看一下IL
 
Test()→.ctor:void()
.method public hidebysig specialname rtspecialname
        instance void .ctor() cil managed
{
 // 代码大小       31 (0x1f)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: call       instance void [mscorlib]System.Object::.ctor()
 IL_0006: nop
 IL_0007: nop
 IL_0008: ldarg.0
 IL_0009: ldc.i4.1
 IL_000a: stfld      int32 ConsoleApplication1.Test::a
 IL_000f: ldarg.0
 IL_0010: ldc.i4.2
 IL_0011: stfld      int32 ConsoleApplication1.Test::b
 IL_0016: ldarg.0
 IL_0017: ldc.i4.3
 IL_0018: stfld      int32 ConsoleApplication1.Test::c
 IL_001d: nop
 IL_001e: ret
} // end of method Test::.ctor
Test(int i)→.ctor:void(int32)
.method public hidebysig specialname rtspecialname
        instance void .ctor(int32 i) cil managed
{
 // 代码大小       10 (0xa)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: call       instance void ConsoleApplication1.Test::.ctor()
 IL_0006: nop
 IL_0007: nop
 IL_0008: nop
 IL_0009: ret
} // end of method Test::.ctor
Test(string s)→.ctor:void(string)
.method public hidebysig specialname rtspecialname
        instance void .ctor(string s) cil managed
{
 // 代码大小       10 (0xa)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: call       instance void ConsoleApplication1.Test::.ctor()
 IL_0006: nop
 IL_0007: nop
 IL_0008: nop
 IL_0009: ret
} // end of method Test::.ctor
会发现,在有参数的两个构造函数中的IL要少很多,这样就能减少IL代码量。
 
在类中,如果有初始化的静态字段,会在静态构造函数中来实现,不过静态构造函数只能有一个,所以这个在代码量中问题不会存在。
 
可以看出,在类中,如果有初始化的字段,他的执行要先于对象的生成,即构造函数的执行(完全执行)。
标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试性能评估。4.1测试环境与方法介绍测试环境配置采用的测试方法。4.2功能测试结果展示各功能模块的测试结果问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果技术创新。5.2未来展望指出系统局限性并提出后续优化方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值