作者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://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1460986881.A.767.html
1F:→ Litfal: A1: lazy应该不用解释,eager是静态初始化时new出来。 04/20 17:21
2F:→ Litfal: 而静态初始化会在第一次用到该类别时进行。 04/20 17:22
3F:→ Litfal: 因为这是由CLR控制的,所以你无法控制静态建构什麽时候被 04/20 17:29
4F:→ Litfal: 执行,只能确定一定是在任何类别成员被使用之前执行。 04/20 17:30
5F:→ Litfal: (MSDN原文) The user has no control on when the static 04/20 17:30
6F:→ Litfal: constructor is executed in the program. 04/20 17:31
7F:→ Litfal: Q2. readonly是设计,观念就是不应该会被更改,无论内外 04/20 17:35
8F:→ Litfal: Q3. 资源笨重且不常使用则lazy较佳,轻量则eager较好写又 04/20 17:38
9F:→ Litfal: 能简单避免多执行绪问题 04/20 17:38
10F:→ ssccg: static getInstance这种lazy和eager通常差别不大,因为第一 04/20 18:12
11F:→ ssccg: 次用通常就是getInstance 04/20 18:13
12F:→ ssccg: 除非就像你说的有其他static method有机会先被用 04/20 18:21
感谢2位大大的说明
※ 编辑: poloball (27.147.0.247), 04/23/2016 16:24:50