作者poloball (吃不胖真無奈…)
看板C_Sharp
標題[問題] singleton pattern物件初始化的時間點
時間Mon Apr 18 21:41:16 2016
wiki的說明 singleton pattern 的實現常見有
lazy instantization 跟 eager instantization
依造設計用意
lazy 在第一次使用時才產生實例
eager 是物件載入時產生
不了解何時是所謂的"物件載入"
實際用以下2個class測試, 環境是 vs 2010 express
public class Singleton_lazy
{
private static Singleton_lazy instance;
public static string str = "lazy public attribute";
private Singleton_lazy()
{
Console.WriteLine("Singleton lazy initialized");
}
public static Singleton_lazy getInstance()
{
if (instance == null)
instance = new Singleton_lazy();
return instance;
}
public static string String()
{
return "lazy public method";
}
}
public class Singleton_Eager
{
private static readonly Singleton_Eager instance = new Singleton_Eager();
public static string str = "eager public attribute";
private Singleton_Eager()
{
Console.WriteLine("Singleton Eager initialized");
}
public static Singleton_Eager getInstance()
{
return instance;
}
public static string String()
{
return "eager public method";
}
}
測試3種情況
--------------------------------------------------------------
static void Case1()
{
Console.WriteLine("Case1");
Singleton_lazy.getInstance();
Singleton_Eager.getInstance();
}
輸出:
Case1
Singleton lazy initialized
Singleton Eager initialized
都在getInstance時呼叫建構子, 這種情況兩者無差異?
--------------------------------------------------------------
static void Case2()
{
Console.WriteLine("Case2");
Console.WriteLine(Singleton_lazy.String());
Console.WriteLine(Singleton_Eager.String());
Singleton_lazy.getInstance();
Singleton_Eager.getInstance();
}
輸出:
Case2
lazy public method
Singleton Eager initialized
eager public method
Singleton lazy initialized
呼叫public method時lazy不會產生實例, eager會
--------------------------------------------------------------
static void Case3()
{
Console.WriteLine("Case3");
Console.WriteLine(Singleton_lazy.str);
Console.WriteLine(Singleton_Eager.str);
Singleton_lazy.getInstance();
Singleton_Eager.getInstance();
}
輸出:
Singleton Eager initialized
Case3
lazy public attribute
eager public attribute
Singleton lazy initialized
使用public屬性, eager會搶在第一行程式前就產生實例
幾點疑問:
Q1 產生實例的時間點如何決定? 不知如何解讀這個結果
Q2 第2種方式readonly keyword是必要的嗎?
已經是private成員 還有可能被外部改動到嗎, 或只是避免內部自己改到?
Q3 如果需要實現singleton的物件, 沒有public static的屬性或方法
是否這兩種實現方式沒有差別?
先謝謝大大回答
--
「俺が思うに、この世の全ては、ゲームだ。」
~ 桐谷修二 ~
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 27.147.0.247
※ 文章網址: https://www.ptt.cc/bbs/C_Sharp/M.1460986881.A.767.html
→ Litfal: A1: lazy應該不用解釋,eager是靜態初始化時new出來。 04/20 17:21
→ Litfal: 而靜態初始化會在第一次用到該類別時進行。 04/20 17:22
→ Litfal: 因為這是由CLR控制的,所以你無法控制靜態建構什麼時候被 04/20 17:29
→ Litfal: 執行,只能確定一定是在任何類別成員被使用之前執行。 04/20 17:30
→ Litfal: (MSDN原文) The user has no control on when the static 04/20 17:30
→ Litfal: constructor is executed in the program. 04/20 17:31
→ Litfal: Q2. readonly是設計,觀念就是不應該會被更改,無論內外 04/20 17:35
→ Litfal: Q3. 資源笨重且不常使用則lazy較佳,輕量則eager較好寫又 04/20 17:38
→ Litfal: 能簡單避免多執行緒問題 04/20 17:38
→ ssccg: static getInstance這種lazy和eager通常差別不大,因為第一 04/20 18:12
→ ssccg: 次用通常就是getInstance 04/20 18:13
→ ssccg: 除非就像你說的有其他static method有機會先被用 04/20 18:21
感謝2位大大的說明
※ 編輯: poloball (27.147.0.247), 04/23/2016 16:24:50