积极答复者
使用公共初始化构造器为什么能减少生成的代码?

问题
-
在CLR via C#一书中提到,调用公共初始化构造器能减少生成的代码(164页)。
下面的代码,书上说,由于有三个构造器,所以编译生成三次初始化m_x,m_s,m_d的代码,每个构造器一次class SomeType { private Int32 m_x = 5; private String m_s = 'Hi'; private Double m_d = 3.14; private Byte m_b; public SomeType() { } public SomeType( Int32 x) { } public SomeType( String s) { ...; m_d = 10; } }
而下面的代码使用了公共的初始化构造器减少了生成代码。请问,为什么这样会减少生成的代码?
公共的初始化构造器不是也会被调用三次么,那么还是会三次初始化m_x, m_s, m_d。class SomeType { private Int32 m_x ; private String m_s ; private Double m_d; private Byte m_b; public SomeType() { m_x = 5; m_s = "Hi"; m_d = 3.14; } public SomeType( Int32 x) :this(){ m_x = x; } public SomeType( String s):this() { m_s = s; } public SomeType( Int32 x,String s):this() { m_x = x; m_s = s; } }
答案
-
是的, 我在說明的就是這樣的方式會讓代碼數量增加,而且也會讓某些 fields 被重複指派
委托构造函数只能减少代码量,fields还是会重复指派,也就是说不能减少执行次数。要想减少代码执行次数,就得用参数少的去call参数多的构造函数,但这样就起不到委托构造函数的意义了。
比如:
public SomeType() : this(5, "Hi") { }
public SomeType(Int32 x) : this(x, "Hi") { }
public SomeType(String s) : this(5, s) { }
这里5和Hi这样的初始值被多次指定,一旦需要修改就可能导致遗漏,因此一般都是有参的构造函数去call无参的默认构造函数。无参的默认构造函数负责统一初始化,有参的重载构造函数再去执行修改,虽然会重复指派,但增强了代码的可维护性。
- 已标记为答案 我是菜鸟啦 2018年11月26日 12:52
全部回复
-
當你用第一個寫法的時候, 編譯器會在每個構造器加上同樣以下三列程式碼
m_x = 5; m_s = "Hi"; m_d = 3.14
另外, 我通常會讓參數少的呼叫參數多的構造器 , 類似以下這樣
class SomeType { private Int32 m_x; private String m_s; private Double m_d; private Byte m_b; public SomeType() : this(5, "Hi") { } public SomeType(Int32 x) : this(x, "Hi") { } public SomeType(String s) : this(5, s) { } public SomeType(Int32 x, String s) { m_x = x; m_s = s; m_d = 3.14; } }
在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/
- 已建议为答案 Zhanglong WuMicrosoft contingent staff, Moderator 2018年11月21日 8:22
-
有少執行喔
假設你這樣寫
class SomeType { private Int32 m_x = 5; private String m_s = "Hi"; private Double m_d = 3.14; private Byte m_b; public SomeType() { } public SomeType(Int32 x) { m_x = x; } public SomeType(String s) { m_s = s; } }
實際上是這樣執行
class SomeType { private Int32 m_x; private String m_s; private Double m_d; private Byte m_b; public SomeType() { m_x = 5; m_s = "Hi"; m_d = 3.14; } public SomeType(Int32 x) { m_x = 5; m_s = "Hi"; m_d = 3.14; m_x = x; } public SomeType(String s) { m_x = 5; m_s = "Hi"; m_d = 3.14; m_s = s; } }
可以看到在 SomeType(Int32 x) 中, m_x 的指派執行了兩次
在 SomeType(String s) 中, m_s 的指派也是執行兩次
在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/
- 已编辑 Bill ChungMVP 2018年11月23日 10:08
-
你这样写就不再是“委托构造函数”了,起不到减少代码数量的作用,相反增加了代码的数量。委托构造函数一方面是为了减少代码的数量,更重要的是减少代码的重复,进而避免出现构造函数逻辑调整后修改的工作量,也避免了由于遗忘(这一点在大型项目中很常见)而出现的Bug,是一种以可以忽略不计的极小的性能损失来换取代码可维护性的方法。
在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/
- 已编辑 Bill ChungMVP 2018年11月24日 9:15
-
是的, 我在說明的就是這樣的方式會讓代碼數量增加,而且也會讓某些 fields 被重複指派
委托构造函数只能减少代码量,fields还是会重复指派,也就是说不能减少执行次数。要想减少代码执行次数,就得用参数少的去call参数多的构造函数,但这样就起不到委托构造函数的意义了。
比如:
public SomeType() : this(5, "Hi") { }
public SomeType(Int32 x) : this(x, "Hi") { }
public SomeType(String s) : this(5, s) { }
这里5和Hi这样的初始值被多次指定,一旦需要修改就可能导致遗漏,因此一般都是有参的构造函数去call无参的默认构造函数。无参的默认构造函数负责统一初始化,有参的重载构造函数再去执行修改,虽然会重复指派,但增强了代码的可维护性。
- 已标记为答案 我是菜鸟啦 2018年11月26日 12:52