实例构造器和类(引用类型)
生活随笔
收集整理的這篇文章主要介紹了
实例构造器和类(引用类型)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
構造器是允許將類型的實例初始化為良好狀態的一種特殊方法。構造器方法在“方法定義元數據表”中始終教.ctor。
創建一個引用類型的實例時,首先為實例的數據字段分配內存,然后初始化對象的附加字段(類型對象指針呵呵同步塊索引),最后調用類型的實例構造器來設置對象的初始狀態。
實例構造器永遠不能被繼承。
如果類的修飾符為abstract,那么編譯器生成的默認構造器的可訪問性就為protected;否則,構造器會被賦予public可訪問性。如果基類沒有提供無參數構造器,那么派生類必須顯示調用一個基類構造器,否則編譯器會報錯。如果類的修飾符為static(sealed和abstract),編譯器根本不會再類的定義中生成一個默認構造器。
C#編譯器提供一個簡化的語法,允許以“內聯”方式初始化實例字段。但在幕后,它會將這種語法轉換成構造器方法中的代碼來執行初始化。這同時提醒我們注意代碼的膨脹效應。
所謂內聯,是指在代碼中直接賦值來初始,而不是通過構造器。
??? 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;
??? }
編譯器為這三個構造器方法生成代碼時,在每個方法開始的位置,都會包含用于初始化m_x,m_s和m_d的代碼。在這些初始化代碼之后,編譯器會插入對基類構造器的調用。再然后,會插入構造器自己的代碼。查看該類的IL代碼,發現有三個構造方法:
?
每個.ctor方法中都會初始化m_x,m_s和m_d。如下IL代碼(這里只是貼出了無參數構造器的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
如果有幾個以初始化的實例字段和大量重載的構造器方法,可考慮不是在定義字段時初始化,而是創建單個構造器來執行這些公共的初始化。然后,讓其他構造器顯示調用這個公共初始化構造器。這樣可以減少生成的代碼。如下演示:
??????? 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;
??????? }
??? }
編譯后,會發現無參數的構造函數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
在該構造器中先調用無參數的構造器(如上紅色),然后再進行本身構造器的實例化。
由此可見,這樣很好的防止了代碼膨脹。
轉載于:https://www.cnblogs.com/rayxin/archive/2011/05/17/2049123.html
總結
以上是生活随笔為你收集整理的实例构造器和类(引用类型)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 避免将项目名称用作映射类型名称
- 下一篇: 您不能不知的ToString()方法