文章标签 ‘Flyweight’

[转载]C#字符串与享元(Flyweight)模式 – winter-cn – 博客园. 写这个文章,主要是因为网上对C#字符串和享元模式的误解比较多。 Flyweight模式 先说这名字,fly呢,就是苍蝇,没错这里面不是飞的意思,是苍蝇的意思,weight大家都知道,就是重量,苍蝇的重量,就是非常非常轻的意思。所以Flyweight模式就是处理非常非常轻量级对象的一个东西。 Flyweight的目标是解决大量细粒度对象的内存消耗问题,当然,巧妇难为无米之炊,任何模式和手法都不能凭空造出内存来,所以享元模式针对的情况是这些细粒度对象的中数据有重复的情况。 Flyweight的做法是,把对象的状态(通常用属性表示),分成两个部分,一部分是内部状态,另一部分是外部状态。内部状态是不易重复的(或者说必要的),外部状态是易重复的。所以,Flyweight把外部状态提取出来共享,这样就一定程度解决了内存占用问题。 C#中的字符串不是Flyweight模式 在网上常常可以看到一个说法,说C#中的字符串使用了Flyweight模式,开门见山地说,这个说法是错误的。 错在哪里呢?按照上文的介绍,错就错在字符串它没有所谓的“内部状态”。 通常讲字符串是享元的原因就是以下代码: string a = “Hello World”; Console.WriteLine(Object.ReferenceEquals(a, “Hello World”)); //True 当使用字符串直接量的时候,不论你写了多少个”Hello World”,最终内存里面只有一个字符串对象。 运行时创建的字符串并不在此列,可以使些手段,强制在内存里面产生新的字符串。 string a = “Hello World”; Console.WriteLine(Object.ReferenceEquals(a, new String(“Hello World”.ToCharArray())));  //False 因为我们强行调用了new,所以这个字符串跟内存中的直接量”Hello World”对应的对象不是同一个。 有趣的是,C#还允许强制把一个字符串加入到(如果已经有了,就只是找出来)字符串池里面。 string a = “Hello World”; string b = String.Intern(new String(“Hello World”.ToCharArray())); Console.WriteLine(Object.ReferenceEquals(a,b) ); 或者 string a [...]

2012年1月26日18:42 评论关闭
备案信息:冀ICP备10007948号