[問題] singleton pattern物件初始化的時間點

看板C_Sharp (C#)作者 (吃不胖真無奈…)時間9年前發表 (2016/04/18 13:41), 9年前編輯推噓0(0012)
留言12則, 2人參與, 最新討論串1/1
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

04/20 17:21, , 1F
A1: lazy應該不用解釋,eager是靜態初始化時new出來。
04/20 17:21, 1F

04/20 17:22, , 2F
而靜態初始化會在第一次用到該類別時進行。
04/20 17:22, 2F

04/20 17:29, , 3F
因為這是由CLR控制的,所以你無法控制靜態建構什麼時候被
04/20 17:29, 3F

04/20 17:30, , 4F
執行,只能確定一定是在任何類別成員被使用之前執行。
04/20 17:30, 4F

04/20 17:30, , 5F
(MSDN原文) The user has no control on when the static
04/20 17:30, 5F

04/20 17:31, , 6F
constructor is executed in the program.
04/20 17:31, 6F

04/20 17:35, , 7F
Q2. readonly是設計,觀念就是不應該會被更改,無論內外
04/20 17:35, 7F

04/20 17:38, , 8F
Q3. 資源笨重且不常使用則lazy較佳,輕量則eager較好寫又
04/20 17:38, 8F

04/20 17:38, , 9F
能簡單避免多執行緒問題
04/20 17:38, 9F

04/20 18:12, , 10F
static getInstance這種lazy和eager通常差別不大,因為第一
04/20 18:12, 10F

04/20 18:13, , 11F
次用通常就是getInstance
04/20 18:13, 11F

04/20 18:21, , 12F
除非就像你說的有其他static method有機會先被用
04/20 18:21, 12F
感謝2位大大的說明 ※ 編輯: poloball (27.147.0.247), 04/23/2016 16:24:50
文章代碼(AID): #1N5EG1Td (C_Sharp)
文章代碼(AID): #1N5EG1Td (C_Sharp)