懒汉与饿汉

6lilu9 2018-06-21 05:29:46
public class WordManager
{
public static Word._Application App;

public WordManager()
{
App = new Word.Application();
}
}


public class WordManager[code=csharp]

{
public static Word._Application App = new Word.Application();

public WordManager()
{
}
}[/code]
以上两种,哪种好。

如果我用下面代码调用,
WordManager wm= new WordManager();
,其实两种效果是一样的吧?
...全文
1024 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 17 楼 sxl514286339 的回复:
【好吧,上面的说辞 云山雾罩,我自己都无法表达:大意就一个:微软底层很多 字段都是在 构造函数中 初始化的】


我猜测这更多地是从反编译工具上看源代码的印象。

因为 .net 并没有什么在声明时初始化值的功能,lz 第2段代码是c#语法,而不是 .net 的语法。c#的第 2 段语法糖在被 c# 编译器编译完了之后,就会自动跑到实例化方法里去了。所以要注意这个 c# 与 .net 的区别。
  • 打赏
  • 举报
回复
可能 lz 问题关注的重点最终也不在单例模式,而是在于”懒汉、饿汉“上。
  • 打赏
  • 举报
回复
另外,其实我觉得"懒汉、饿汉“这类雷人的名词儿其实也可也可以少用。可以看到有多少人整天纠结这些雷人的名词儿而上 csdn 来问?

直截了当地说”只有第一次访问时才实例化,而不是类型/对象初始化时实例化“就可以了。GOF 的《设计模式》里边一大堆雷人的名词儿,也没见有 .net framework 中的各种编程模式清楚实用。很多时候对于基本的设计模式,直截了当地说技术术语,而不是用雷人的隐喻名词儿,反而更好!
  • 打赏
  • 举报
回复
懒汉、饿汉的区别,不是说实例化代码写到初始化方法之内还是之外。lz 贴的代码根本没有懒汉代码,所以搞清楚懒汉代码应该怎样写这才是重点。
JH_bigGreen 2018-06-25
  • 打赏
  • 举报
回复
第二个比较好,第一个写的有问题
tjhdaxia 2018-06-25
  • 打赏
  • 举报
回复
都没实现单例设计模式
  • 打赏
  • 举报
回复
第二个好一点
wanghui0380 2018-06-22
  • 打赏
  • 举报
回复
请想象一下,你封装了人家怎么用?用着出不出错?

我同时new 两个 WordManager 第一个我写1亿个A,第2个我要写1个B

请问他到会怎么样。

---------------------------------------
所以就算是要写一些通用的填充模板,那也是写成扩展方法(对Word._Application类型扩展)或者把Word._Application写成属性(让外面的人自己给你传Word._Application的实例)或者他就是私有的(当然如果你不想一开始就加载,你想按需加载,也可以是lazy<Word._Application>)。

正怒月神 2018-06-22
  • 打赏
  • 举报
回复
如果一直要使用这个对象,
那么直接
public static WordManager
{
WordManager wm;
static WordManager
{
wm=new ......();
}
}
  • 打赏
  • 举报
回复
要注意的是,对于“GOF设计模式”来说,所谓的单例是要写
public class WordManager
{

private WordManager()
{
}

。。。。。。。。。。。。。。。。。。。
}

这里强调的是 private。它们生怕有人会创建 WordManager 对象实例,而又不想只是定义
public static class WordManager
这样的静态类。

这才是 GOF 在20年前的写的设计模式那本书中单例模式的比较“矫情”的点!
wanghui0380 2018-06-22
  • 打赏
  • 举报
回复
无所谓对错,这2代码代码都有bug,都的树个牌子“前方有坑,请小心驾驶”

其实,这个玩意不必封,你封了反而多余。你不封,别人在外面使用都是不出bug的标准写法
using(word.application)
{
}

你封了,别人反而能写出大堆出bug的代码。

ps:对于word.application请别折腾,你单件了,静态了问题更大。当然其实我们本身也不建议使用word.application,vsto的如果宿主就是office没问题(比如word插件),但是如果宿主是普通程序,开office进程,关office进程,负担相当重
  • 打赏
  • 举报
回复
占用数据小的话,直接在static情况下new了也无所谓
  • 打赏
  • 举报
回复
一个在运行时(而不是类型实例化时)赋值的代码应该是类似这样的
public class WordManager
{
public static Word._Application _App;

public static Word._Application App
{
get{
if( _App==null)
_App = new Word.Application();
return _App;
}
}
}

而你哪里写了这种代码?

你并没有。所以你懂得的这个结论.............
  • 打赏
  • 举报
回复
对于代码
public static Word._Application App = new Word.Application();
来说,它就是在类型实例化过程中 new 一个对象实例并且赋值给 App 变量。.net 并没有这种语法,这纯粹是 c# 编译器的语法糖,它编译出来的结果就跟第三种代码(我贴的代码)是一样的。

所以这个时候就可以说“是一样的”,只是语法不同而已。
  • 打赏
  • 举报
回复
这两个代码,第一个显然是一个 bug,它在每一次实例化对象时都把 static 的变量 App 给覆盖了,所以它显然是bug。

第二个代码,就等于是
public class WordManager
{
public static Word._Application App;

static WordManager()
{
App = new Word.Application();
}
}
是在类型对象实例化时一次性为 App 赋值。


第一段代码,连对错都不满足,所以无所谓好坏!
SoulRed 2018-06-22
  • 打赏
  • 举报
回复

如果你百分百的确定要使用这个单例,那么用饿汉。
如果你不确定整个程序生命周期是否能用到。那么用懒汉,可以让程序占用内存更小。。。
吹风的兔子 2018-06-22
  • 打赏
  • 举报
回复
一个变量的初始化,
是在 构造函数里面好,还是 直接就初始化。

建议:在构造函数里面比较好。

原因:
我之前进行过 WinForm的重绘,其中 DataGridView 控件的 滚动条,我想重绘。
微软底层的 字段肯定是私有的,没关系,我可以反射 替换成自己美化后的。
但是:滚动条的初始化操作 可就尴尬了。
—— 幸好:微软底层 是在 构造函数里面 进行的 初始化。

我只需要继承,然后反射修改 滚动条字段,替换,搞定——接下来的 初始化操作 由微软底层帮我进行。
—— 从那以后,我就基本不在 类里面直接定义 那种 需要new完之后,还要一堆初始化的对象了。

【好吧,上面的说辞 云山雾罩,我自己都无法表达:大意就一个:微软底层很多 字段都是在 构造函数中 初始化的】

sp1234_maJia 2018-06-22
  • 打赏
  • 举报
回复
“懒汉”的意思,是说只有运行到相关的业务处理代码、需要访问 App 实例时才真正创建 Application 对象实例,而不是类型初始化时就去创建对象。

你贴的代码还根本没有“懒汉”的意识。
足球中国 2018-06-22
  • 打赏
  • 举报
回复
两种生命周期不一样。不是一回事。
圣殿骑士18 2018-06-22
  • 打赏
  • 举报
回复
不讲代码的错误,只看你的意图的话。两者没有本质差别。
我会坚决的用方法2,因为简约。

如果某些特殊情况下,必须用方法1,那才用方法1。
什么时候是特殊情况?比如还有一个App2变量也要初始化,而App2依赖App,那么两者都放到构造方法中进行初始化。否则你是无法知道App和App2哪个被先初始化的。
加载更多回复(3)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧