实例构造器和类(引用类型)
生活随笔
收集整理的這篇文章主要介紹了
实例构造器和类(引用类型)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
構(gòu)造器是允許將類型的實(shí)例初始化為良好狀態(tài)的一種特殊方法。構(gòu)造器方法在“方法定義元數(shù)據(jù)表”中始終教.ctor。
創(chuàng)建一個(gè)引用類型的實(shí)例時(shí),首先為實(shí)例的數(shù)據(jù)字段分配內(nèi)存,然后初始化對(duì)象的附加字段(類型對(duì)象指針呵呵同步塊索引),最后調(diào)用類型的實(shí)例構(gòu)造器來(lái)設(shè)置對(duì)象的初始狀態(tài)。
實(shí)例構(gòu)造器永遠(yuǎn)不能被繼承。
如果類的修飾符為abstract,那么編譯器生成的默認(rèn)構(gòu)造器的可訪問(wèn)性就為protected;否則,構(gòu)造器會(huì)被賦予public可訪問(wèn)性。如果基類沒(méi)有提供無(wú)參數(shù)構(gòu)造器,那么派生類必須顯示調(diào)用一個(gè)基類構(gòu)造器,否則編譯器會(huì)報(bào)錯(cuò)。如果類的修飾符為static(sealed和abstract),編譯器根本不會(huì)再類的定義中生成一個(gè)默認(rèn)構(gòu)造器。
C#編譯器提供一個(gè)簡(jiǎn)化的語(yǔ)法,允許以“內(nèi)聯(lián)”方式初始化實(shí)例字段。但在幕后,它會(huì)將這種語(yǔ)法轉(zhuǎn)換成構(gòu)造器方法中的代碼來(lái)執(zhí)行初始化。這同時(shí)提醒我們注意代碼的膨脹效應(yīng)。
所謂內(nèi)聯(lián),是指在代碼中直接賦值來(lái)初始,而不是通過(guò)構(gòu)造器。
??? internal sealed class SomeType
??? {
??????? public SomeType() { }
??????? public SomeType(Int32 x) { }
??????? public SomeType(String s) { }
??????? private Int32 m_x = 5;
??????? private String m_s = "Hello World";
??????? private Double m_d = 3.14159;
??????? private Byte m_b;
??? }
編譯器為這三個(gè)構(gòu)造器方法生成代碼時(shí),在每個(gè)方法開(kāi)始的位置,都會(huì)包含用于初始化m_x,m_s和m_d的代碼。在這些初始化代碼之后,編譯器會(huì)插入對(duì)基類構(gòu)造器的調(diào)用。再然后,會(huì)插入構(gòu)造器自己的代碼。查看該類的IL代碼,發(fā)現(xiàn)有三個(gè)構(gòu)造方法:
?
每個(gè).ctor方法中都會(huì)初始化m_x,m_s和m_d。如下IL代碼(這里只是貼出了無(wú)參數(shù)構(gòu)造器的IL代碼):
.method public hidebysig specialname rtspecialname
??????? instance void? .ctor() cil managed
{
? // 代碼大小?????? 43 (0x2b)
? .maxstack? 8
? IL_0000:? ldarg.0
? IL_0001:? ldc.i4.5
? IL_0002:? stfld????? int32 ctor.SomeType::m_x
? IL_0007:? ldarg.0
? IL_0008:? ldstr????? "Hello World"
? IL_000d:? stfld????? string ctor.SomeType::m_s
? IL_0012:? ldarg.0
? IL_0013:? ldc.r8???? 3.1415899999999999
? IL_001c:? stfld????? float64 ctor.SomeType::m_d
? IL_0021:? ldarg.0
? IL_0022:? call?????? instance void [mscorlib]System.Object::.ctor()
? IL_0027:? nop
? IL_0028:? nop
? IL_0029:? nop
? IL_002a:? ret
} // end of method SomeType::.ctor
如果有幾個(gè)以初始化的實(shí)例字段和大量重載的構(gòu)造器方法,可考慮不是在定義字段時(shí)初始化,而是創(chuàng)建單個(gè)構(gòu)造器來(lái)執(zhí)行這些公共的初始化。然后,讓其他構(gòu)造器顯示調(diào)用這個(gè)公共初始化構(gòu)造器。這樣可以減少生成的代碼。如下演示:
??????? public SomeType1()
??????? {
??????????? m_x = 5;
??????????? m_s = "Hello World";
??????????? m_d = 3.14159;
??????????? m_b = 0xff;
??????? }
??????? public SomeType1(Int32 x)
??????????? : this()
??????? {
??????????? m_x = x;
??????? }
??????? public SomeType1(String s)
??????????? : this()
??????? {
??????????? m_s = s;
??????? }
??????? public SomeType1(Int32 x, String s)
??????????? : this()
??????? {
??????????? m_s = s;
??????????? m_x = x;
??????? }
??? }
編譯后,會(huì)發(fā)現(xiàn)無(wú)參數(shù)的構(gòu)造函數(shù)IL代碼與上面的IL一樣,而在SomeType1(Int32 x)中的IL代碼中如下:
.method public hidebysig specialname rtspecialname
??????? instance void? .ctor(int32 x) cil managed
{
? // 代碼大小?????? 17 (0x11)
? .maxstack? 8
? IL_0000:? ldarg.0
? IL_0001:? call?????? instance void ctor.SomeType1::.ctor()
? IL_0006:? nop
? IL_0007:? nop
? IL_0008:? ldarg.0
? IL_0009:? ldarg.1
? IL_000a:? stfld????? int32 ctor.SomeType1::m_x
? IL_000f:? nop
? IL_0010:? ret
} // end of method SomeType1::.ctor
在該構(gòu)造器中先調(diào)用無(wú)參數(shù)的構(gòu)造器(如上紅色),然后再進(jìn)行本身構(gòu)造器的實(shí)例化。
由此可見(jiàn),這樣很好的防止了代碼膨脹。
轉(zhuǎn)載于:https://www.cnblogs.com/rayxin/archive/2011/05/17/2049123.html
總結(jié)
以上是生活随笔為你收集整理的实例构造器和类(引用类型)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 避免将项目名称用作映射类型名称
- 下一篇: 您不能不知的ToString()方法