记得我在读大学时听老师讲C++,我就在想老师干什么总是讲面向对象的两个特征,多态,继承,感觉自己用C++编写小程序的时候根本就没用到,干嘛总是强调这两个特征。我想很多人对这两个特征应用的不多,因为我们现在属于初级程序员,公司没有理由让我们去底层的框架开发或者基础类库书写。但是这不是我们不去思考的原因。
让我们在来看看泛型学习中两个函数吧,记住,用需求变化的眼光看这两个函数。
public static object LoadFromFile(Type typeToLoad, string filePath) { XmlSerializer factory = new XmlSerializer(typeToLoad); if (File.Exists(filePath)) { using (TextReader r = new StreamReader(filePath)) { object rval = factory.Deserialize(r); return rval; } } return default(object); } public static void SaveToFile(string filePath, object obj) { Type theType = obj.GetType(); XmlSerializer factory = new XmlSerializer(theType); using (TextWriter w = new StreamWriter(filePath, false)) { factory.Serialize(w, obj); } }
问题一 :使用该方法的开发者必须指定Type参数,无法通过推断得出
问题二:调用LoadFromFile时得到的返回值是Object,会按照自己的需要进行强制转化
问题三:多次调用此方法会创建过多的XMLSerializer对象,随意创建并销毁不必要的临时对象
对于第三个问题,很多人会说,这简单啊,只需要加一行代码
if(factory==null)
{
XmlSerializer factory = new XmlSerializer(theType);
}
一般情况下是没错的,我之前也经常这样干,看着似乎十分的完美,其实是十分不对的。请你想想,这个theType是不变得的吗,在整个系统中,只会对同一个类型序列化吗?答案肯定是不可能的。因此,系统抛出异常的几率十分的大。
既然类可能是不同的类,我们不就可以将其放入一张绑定不同Type的XMLSerializer的散列表中吗?当然,完全可以实现,但代码估计会比较多。
于是,我们可以使着用泛型去解决问题
public static class SenericXMLPersistenceManager<T> { private static XmlSerializer facotry; public static T LoadFromFile(string filePath) { if (File.Exists(filePath)) { using (XmlReader inputStream = XmlReader.Create(filePath)) { return ReadFromStream(inputStream); } } return default(T); } public static T ReadFromStream(XmlReader inputStream)
{
if (facotry == null)
{
facotry = new XmlSerializer(typeof(T));
}
T rVal = (T)facotry.Deserialize(inputStream);
return rVal;
}
public static void SaveToFile(string filePath, T data) { using (XmlWriter writer = XmlWriter.Create(filePath)) { AddToStream(writer, data); } } public static void AddToStream(System.Xml.XmlWriter outPutStream, T data) { if (facotry == null) { facotry = new XmlSerializer(typeof(T)); } } }
如果我们需要知晓传入参数的类型,通畅可以创建一个泛型实现,将方法的类型参数抽象到泛型参数中,随后编译器即可根据泛型参数创建出所需类型。