返回信息流该文原帖(英文):http://timnewtech.spaces.live.com/blog/cns!9E31159246A468A3!219.entry
今天在写Puzzle Quest的Launcher的时候需要用到串行化多个类型的实体,不断的写同样的代码是在是很烦人的事情(偶素懒人)~
然后突发奇想搞出个这样的东东来~
原理:泛型类实质上说并不能算一个"类",而是类似于模板一类的东东。因此一个泛型类将会对应一系列的泛型实例。例如List<string>就是List<T>的一个实例。
泛型实例与泛型类本身的关系与类实例和类本身的关系非常相像~这种相似性让我们把泛型实例当作类实例一样使用带来的可能。
为什么要用泛型实例?!
最基本的原因:代码写起来简单(偶说过偶素懒人啦)~使用了使用了Lazy Initialize以后,完全可以把一个类当实例来用~
另外用类而不用实例的原因在于,我们总是可以访问到一个类,但却不一定能找到一个类的实例~
当然有人会说我们可以使用Singleton,这样的话也就能访问到类的唯一实例了!但是我说过我很Lazy~我讨厌写类似于这样的代码:
SomeClass.DefaultInstance.Foo();
我觉得DefaultInstance很碍眼,我喜欢这样的代码:
SomeClass.Foo();
因此我采用了Static Class。
关于Weak Reference
关于我为什么要使用Weak Reference?因为我考虑到了下列这种情形。
无论我们使用多少次类型T的SerializerManager,.net Runtime总会为其生成一个泛型实例!该实例中还会有一个XmlSerialzier的类实例,而且这个实例所占的资源还不小(.net 会反射所Serializer所指向的类型,然后使用CodeDom生成具体的Serializer代码,CodeDOM所占的资源可不少)!
假设我们仅仅是临时用到一下某个类型的序列化器,极端情况,甚至是一个运行时的匿名类型。这样内存里会存在大量的垃圾SerializerManager<T>实例。
由于是静态类的静态成员,GC肯定不会理会这些垃圾。内存里就会出现大量占用资源的垃圾XmlSerialzier实例。
这时候我采用了WeakReference,这是GC就知道这些XmlSerialzier是可以回收的,因此在必要的时候就会处理掉这些垃圾实例。
当然GC也会有犯错的时候,可能会把有用的XmlSerialzier也处理掉~但是没有关系~因为当Target为null的时候,WeakReference的IsAlive属性就会为False~于是Serializer属性的Get方法就会重新创建该实例!
=======================Source Code =====================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
namespace PuzzleQuestLauncher.RuntimeEntities
{
public static class SerializerManager<T>
{
static SerializerManager()
{
refSerializer = new WeakReference(null);
}
private static WeakReference refSerializer;
public static XmlSerializer Serilaizer
{
get
{
if (!refSerializer.IsAlive)
refSerializer.Target = new XmlSerializer(typeof(T));
return refSerializer.Target as XmlSerializer;
}
}
public static void Serialize(string fileName, T entity)
{
FileStream FS = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
Serilaizer.Serialize(FS, entity);
FS.Close();
}
public static T Deserialize(string fileName)
{
T result;
FileStream FS = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
result = (T)Serilaizer.Deserialize(FS);
FS.Close();
return result;
}
}
}
========================= 代码使用实例 ==================
public static void Update(PatchEntity entity)
{
string PatchInfo = Path.Combine(Runtime.PatchLibrary, Path.ChangeExtension(entity.PatchFileName, ".PatchInfo"));
SerializerManager<PatchEntity>.Serialize(PatchInfo, entity);
}
private static void Refresh(PatchLibrary library)
{
library.Patches.Clear();
string[] patchFiles = Directory.GetFiles(Runtime.PatchLibrary, "*.zip");
if (patchFiles.Length == 0)
return;
foreach (string foPatchFile in patchFiles)
{
string PatchInfo = Path.ChangeExtension(foPatchFile, ".PatchInfo");
if (File.Exists(PatchInfo))
{
PatchEntity entity = SerializerManager<PatchEntity>.Deserialize(PatchInfo); library.Patches.Add(entity);
}
else
{
library.Patches.Add(new PatchEntity
{
Name = Path.GetFileNameWithoutExtension(foPatchFile),
Author = "<Unknown>",
Description = string.Empty,
PatchFileName = Path.GetFileName(foPatchFile)
}
);
}
}
}
======================挖坑灌水的分割线====================
关于Space的原文:
原文可能打不开~GFW不知道为什么原因,不定期的封杀我的Space~我的Google Page~我的Twister~我不知道我什么时候惹到了GFW的孩子~不过事情就是这样了~我也没办法~
如果想看原文的孩子专业点方法可以用Vidalia或无界~
简单的方法可以用下列链接(感谢Google翻译~嗯~)
http://translate.google.cn/translate?u=http%3A%2F%2FTimNewTech.Spaces.Live.Com&sl=zh-CN&tl=zh-CN&hl=zh-CN&ie=UTF-8
======================挖坑灌水的分割线====================
To ZWZ:
我基本搞明白了PQ的Game Data的加载方式了~我发现可以利用PQ的Patch机制,不需要修改原文件也可以让自定义的Xml和LUA其作用!
我现在搞出一大堆Patch包~多了我就自己都搞不明白哪个是哪个了~于是弄了个Launcher~
来张界面图:
这是一条镜像帖。来源:北邮人论坛 / soft-design / #27515同步于 2008/6/27
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
【技术帖】【Original】静态泛型实例 - SerialzierManager
TimNew
2008/6/27镜像同步5 回复
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
windy?猜到lz是哪个牛了
【 在 TimNew (米良家de粮) 的大作中提到: 】
: 该文原帖(英文):http://timnewtech.spaces.live.com/blog/cns!9E31159246A468A3!219.entry
: 今天在写Puzzle Quest的Launcher的时候需要用到串行化多个类型的实体,不断的写同样的代码是在是很烦人的事情(偶素懒人)~
: 然后突发奇想搞出个这样的东东来~
: ...................
【 在 zwz 的大作中提到: 】
: 赞Launcher,gmail我一份吧,顺便伸手Vidalia,无界最近速度不稳
: ps.你的space rss似乎也被封了,最近的更新抓不到了。。。可怜的娃
App in Construction....
完工给你Mail一份~PS,呵呵~似乎需要.net 3.5的CLR,因为我一个不小心使了Linq筛选列表里的对象~HOHO~
Vidalia可以到http://vidalia-project.net/download.php下载~TOR、Vidalia、和Privoxy都是一个包~另外需要一个SocksCap32,这东东比较好找,可以去 Crsky 刨刨~
至于我的Space嘛~唉~不说啥了~谁让我们出生在世界网络9大奇迹之一的GFW落脚的国家呢~你可以去偶的豆瓣去看看~上面有不用代理破解的方式:
http://www.douban.com/note/13655998/
另外RSS,可以走一个国外的服务器去抓~就可以不受GFW的影响~我不知道Google的服务器行不行~不行你可以在你的Space上抓我的Space的RSS~就肯定没有问题!