序列化包含多种不明类型的集合

序列化包含多种不明类型的集合

 代码:/Files/zhuqil/Kirin.rar

导言:

   你是否曾经想过序列化构造对象,它里面有一个集合,这个集合包含接口或者抽象类?你是否不知道所有的你要序列化的类型?好吧,如果这样,那么我可以帮助你。

使用代码:

   让我们开始.首先,你将要将采用下面的帮助类,将它粘贴到你的项目之中。它将帮助你只用一行代码就能序列化一个对象为XML。

 

ExpandedBlockStart.gif代码
/// <summary>
/// 一个用来序列化的通用类
/// </summary>
public class GenericSerializer
{
    
/// <summary>
    
/// Serializes the given object.
    
/// </summary>
    
/// <typeparam name="T">The type of the object to be serialized.</typeparam>
    
/// <param name="obj">The object to be serialized.</param>
    
/// <returns>String representation of the serialized object.</returns>
    public static string Serialize<T>(T obj)
    {
        XmlSerializer xs 
= null;
        StringWriter sw 
= null;
        
try
        {
            xs 
= new XmlSerializer(typeof(T));
            sw 
= new StringWriter();
            xs.Serialize(sw, obj);
            sw.Flush();
            
return sw.ToString();
        }
        
catch (Exception ex)
        {
            
throw ex;
        }
        
finally
        {
            
if (sw != null)
            {
                sw.Close();
                sw.Dispose();
            }
        }
    }
    
public static string Serialize<T>(T obj, Type[] extraTypes)
    {
        XmlSerializer xs 
= null;
        StringWriter sw 
= null;
        
try
        {
            xs 
= new XmlSerializer(typeof(T), extraTypes);
            sw 
= new StringWriter();
            xs.Serialize(sw, obj);
            sw.Flush();
            
return sw.ToString();
        }
        
catch (Exception ex)
        {
            
throw ex;
        }
        
finally
        {
            
if (sw != null)
            {
                sw.Close();
                sw.Dispose();
            }
        }
    }
    
/// <summary>
    
/// Serializes the given object.
    
/// </summary>
    
/// <typeparam name="T">The type of the object to be serialized.</typeparam>
    
/// <param name="obj">The object to be serialized.</param>
    
/// <param name="writer">The writer to be used for output in the serialization.</param>
    public static void Serialize<T>(T obj, XmlWriter writer)
    {
        XmlSerializer xs 
= new XmlSerializer(typeof(T));
        xs.Serialize(writer, obj);
    }
    
/// <summary>
    
/// Serializes the given object.
    
/// </summary>
    
/// <typeparam name="T">The type of the object to be serialized.</typeparam>
    
/// <param name="obj">The object to be serialized.</param>
    
/// <param name="writer">The writer to be used for output in the serialization.</param>
    
/// <param name="extraTypes"><c>Type</c> array
    
///       of additional object types to serialize.</param>
    public static void Serialize<T>(T obj, XmlWriter writer, Type[] extraTypes)
    {
        XmlSerializer xs 
= new XmlSerializer(typeof(T), extraTypes);
        xs.Serialize(writer, obj);
    }
    
/// <summary>
    
/// Deserializes the given object.
    
/// </summary>
    
/// <typeparam name="T">The type of the object to be deserialized.</typeparam>
    
/// <param name="reader">The reader used to retrieve the serialized object.</param>
    
/// <returns>The deserialized object of type T.</returns>
    public static T Deserialize<T>(XmlReader reader)
    {
        XmlSerializer xs 
= new XmlSerializer(typeof(T));
        
return (T)xs.Deserialize(reader);
    }
    
/// <summary>
    
/// Deserializes the given object.
    
/// </summary>
    
/// <typeparam name="T">The type of the object to be deserialized.</typeparam>
    
/// <param name="reader">The reader used to retrieve the serialized object.</param>
    
/// <param name="extraTypes"><c>Type</c> array
    
///           of additional object types to deserialize.</param>
    
/// <returns>The deserialized object of type T.</returns>
    public static T Deserialize<T>(XmlReader reader, Type[] extraTypes)
       
    {
        XmlSerializer xs 
= new XmlSerializer(typeof(T), extraTypes);
        
return (T)xs.Deserialize(reader);
    }
    
/// <summary>
    
/// Deserializes the given object.
    
/// </summary>
    
/// <typeparam name="T">The type of the object to be deserialized.</typeparam>
    
/// <param name="XML">The XML file containing the serialized object.</param>
    
/// <returns>The deserialized object of type T.</returns>
    public static T Deserialize<T>(string XML)
    {
        
if (XML == null || XML == string.Empty)
            
return default(T);
        XmlSerializer xs 
= null;
        StringReader sr 
= null;
        
try
        {
            xs 
= new XmlSerializer(typeof(T));
            sr 
= new StringReader(XML);
            
return (T)xs.Deserialize(sr);
        }
        
catch (Exception ex)
        {
            
throw ex;
        }
        
finally
        {
            
if (sr != null)
            {
                sr.Close();
                sr.Dispose();
            }
        }
    }
    
public static T Deserialize<T>(string XML, Type[] extraTypes)
    {
        
if (XML == null || XML == string.Empty)
            
return default(T);
        XmlSerializer xs 
= null;
        StringReader sr 
= null;
        
try
        {
            xs 
= new XmlSerializer(typeof(T), extraTypes);
            sr 
= new StringReader(XML);
            
return (T)xs.Deserialize(sr);
        }
        
catch (Exception ex)
        {
            
throw ex;
        }
        
finally
        {
            
if (sr != null)
            {
                sr.Close();
                sr.Dispose();
            }
        }
    }
    
public static void SaveAs<T>(T Obj, string FileName, 
                       Encoding encoding, Type[] extraTypes)
    {
        
if (File.Exists(FileName))
            File.Delete(FileName);
        DirectoryInfo di 
= new DirectoryInfo(Path.GetDirectoryName(FileName));
        
if (!di.Exists)
            di.Create();
        XmlDocument document 
= new XmlDocument();
        XmlWriterSettings wSettings 
= new XmlWriterSettings();
        wSettings.Indent 
= true;
        wSettings.Encoding 
= encoding;
        wSettings.CloseOutput 
= true;
        wSettings.CheckCharacters 
= false;
        
using (XmlWriter writer = XmlWriter.Create(FileName, wSettings))
        {
            
if (extraTypes != null)
                Serialize
<T>(Obj, writer, extraTypes);
            
else
                Serialize
<T>(Obj, writer);
            writer.Flush();
            document.Save(writer);
        }
    }
    
public static void SaveAs<T>(T Obj, string FileName, Type[] extraTypes)
    {
        SaveAs
<T>(Obj, FileName, Encoding.UTF8, extraTypes);
    }
    
public static void SaveAs<T>(T Obj, string FileName, Encoding encoding)
    {
        SaveAs
<T>(Obj, FileName, encoding, null);
    }
    
public static void SaveAs<T>(T Obj, string FileName)
    {
        SaveAs
<T>(Obj, FileName, Encoding.UTF8);
    }
    
public static T Open<T>(string FileName, Type[] extraTypes)
    {
        T obj 
= default(T);
        
if (File.Exists(FileName))
        {
            XmlReaderSettings rSettings 
= new XmlReaderSettings();
            rSettings.CloseInput 
= true;
            rSettings.CheckCharacters 
= false;
            
using (XmlReader reader = XmlReader.Create(FileName, rSettings))
            {
                reader.ReadOuterXml();
                
if (extraTypes != null)
                    obj 
= Deserialize<T>(reader, extraTypes);
                
else
                    obj 
= Deserialize<T>(reader);
            }
        }
        
return obj;
    }
    
public static T Open<T>(string FileName)
    {
        
return Open<T>(FileName, null);
    }
}

 

    现在我们已经了解这个方法了,让我们看看我们的问题所在。举一个例子,我们有一个抽象类,Animal。然后有两个继承Animal的类:Human和Dog。

ExpandedBlockStart.gif代码
public abstract class Animal
{
    
public abstract int Legs
    {
        
get;
        
set;
    }

    
public abstract bool HasTail
    {
        
get;
        
set;
    }
}

public class Human : Animal
{

    
public Human()
    {
        
this.Legs = 2;
        
this.HasTail = false;
    }

    
public override int Legs
    {
        
get;
        
set;
    }

    
public override bool HasTail
    {
        
get;
        
set;
    }

}

public class Dog : Animal
{

    
public Dog()
    {
        
this.Legs = 4;
        
this.HasTail = true;
        
this.Breed = "Black Lab";
    }

    
public override int Legs
    {
        
get;
        
set;
    }

    
public override bool HasTail
    {
        
get;
        
set;
    }

    
public string Breed
    {
        
get;
        
set;
    }
}

 

    现在我们有一个想要序列化的对象。它是HouseHold,它的有一个Animal集合属性:

public class HouseHold
{
    
public HouseHold()
    {
        
this.Residents = new List<Animal>();
    }

    
public List<Animal> Residents
    {
        
get;
        
set;
    }
}

 

   现在,我们序列化这个对象。

ExpandedBlockStart.gif代码
try
{
    HouseHold hh 
= new HouseHold();
    hh.Residents.Add(
new Human());
    hh.Residents.Add(
new Human());
    hh.Residents.Add(
new Dog());

    
string xml = GenericSerializer.Serialize<HouseHold>(hh);
    Console.WriteLine(xml);
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

Console.Read();

 

我们将会得到下面的Exception的Message:

"生成 XML 文档时出错。

 

下面是 InnerException的Message :

"不应是类型 Kirin.Human。使用 XmlInclude 或 SoapInclude 属性静态指定非已知的类型。"

 

这里有个关键字“静态”, 我们可以在每个类的顶部放置XmlInclude属性解决这个问题,如:

ExpandedBlockStart.gif代码
   [XmlInclude(typeof(Animal)), XmlInclude(typeof(Human))]
    
public class HouseHold
    {
        
public HouseHold()
        {
            
this.Residents = new List<Animal>();
        }
     
        
public List<Animal> Residents
        {
            
get;
            
set;
        }
    }

 

  但如果我们不知道的继承Animal的所有类,如果我们的应用是可延展的,需要能够使用由用户自定义类型,上面的代码是解决不了问题的。让我们向下看,我会告诉你如何可以做到的。

   首先,我们要做的是使HouseHold类实现IXmlSerializable接口,这样我们就可以拦截这个对象的序列化,我们自己去序列它。

  接着,我们构建一个方法,能检查所有的类型,在这个例子中,我们使用反射去查询的所有继承了Animal类的程序集。 

ExpandedBlockStart.gif代码
public class HouseHold : IXmlSerializable
{
    
private static Type[] _animalTypes;

    
static HouseHold()
    {
        _animalTypes 
= GetAnimalTypes().ToArray();
    }

    
public HouseHold()
    {
        
this.Residents = new List<Animal>();
    }

    
public List<Animal> Residents
    {
        
get;
        
set;
    }

    
#region IXmlSerializable Members

    
public System.Xml.Schema.XmlSchema GetSchema()
    {
        
return null;
    }

    
public void ReadXml(System.Xml.XmlReader reader)
    {
        
bool wasEmpty = reader.IsEmptyElement;
        reader.Read();
        
if (wasEmpty)
            
return;

        reader.MoveToContent();
        reader.ReadStartElement(
"Residents");
        
this.Residents = GenericSerializer.Deserialize<List<Animal>>(reader, _animalTypes);
        reader.ReadEndElement();

        
//Read Closing Element
        reader.ReadEndElement();
    }

    
public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteStartElement(
"Residents");
        GenericSerializer.Serialize
<List<Animal>>(this.Residents, writer, _animalTypes);
        writer.WriteEndElement();
    }

    
#endregion

    
public static List<Type> GetAnimalTypes()
    {

        List
<Type> types = new List<Type>();

        Assembly asm 
= typeof(HouseHold).Assembly;

        Type tAnimal 
= typeof(Animal);

        
//Query our types. We could also load any other assemblies and
        
//query them for any types that inherit from Animal

        
foreach (Type currType in asm.GetTypes())
        {
        
if (!currType.IsAbstract
            
&& !currType.IsInterface
            
&& tAnimal.IsAssignableFrom(currType))
            types.Add(currType);
        }

        
return types;
    }
}

    现在,我们运行我们的测试代码,能顺利通过。希望对你有所帮助,谢谢!

转载于:https://www.cnblogs.com/tangself/archive/2009/12/16/1625240.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习入门方法推荐(少走弯路)入门视频推荐

入门可以看看下列的几个课程。第一第二个公认的经典了。1、首先当然是吴恩达的经典机器学习了&#xff0c; 可以在万能的b站搜&#xff0c;也可以在网易公开课搜 吴恩达机器学习http://study.163.com/course/courseMain.htm?courseId10045700292、台大林轩田教授的机器学习基石…

NLP大神推荐的机器学习入门书单(附大量百度网盘电子书)

转载自&#xff1a;http://blog.csdn.net/surgent777/article/details/53895048 继NLP之后&#xff0c;我又开了ML这个大坑。这是因为NLP涉及到太多的ML模型&#xff0c;仅仅拿过来用的话&#xff0c;我实现的HanLP已经快到个人极限了。而模型背后的原理、如何优化、如何并行化…

$HOME/$user/.权限导致用户无法登陆图形界面

在redhat linux下&#xff0c;用户登陆图形界面时将在$HOME/$user/.目中添加隐藏文件&#xff08;以.开头的文件&#xff09;&#xff0c;如果在无意中将$HOME/$user/.的写权限去除&#xff0c;将会导致用户无法成功登陆gnome&#xff0c;在正确输入用户名和密码的情况下&#…

想要入坑机器学习?这是MIT在读博士的AI心得

从科研社区中汲取营养找论文AI 领域的论文可以在 arXiv 上找到和发布。现在的论文数量非常令人振奋。社区中的许多人降低了从噪声中分辨出信号的难度。Andrej Karpathy 开发了 arXiv sanity preserver&#xff0c;帮助分类、搜索和过滤特征。Miles Brundage 每晚都在推特上发布…

修改EIGRP 路径cost 值,以及分析和实现等价与非等价负载均衡

一、拓扑图&#xff1a;二、配置各路由器的IP和EIGRP 协议&#xff0c;并保证邻接关系的形成。1、我要达到的目的是要让R2到192.168.14.0/24这个网段能在R2和R1断开之后&#xff0c;形成网网络的快速收敛。因为根据EIGRP 的次优路径进拓扑关系的形成条件是要满足FC&#xff08;…

C++函数的用法:erase函数

前面的文章中提到过如何向容器中添加元素&#xff0c;这里介绍一个如何删除容器中元素的函数&#xff0c;包括顺序容器和关联容器。 就是这个erase函数&#xff0c;基本用法如下&#xff1a; c.erase(p)------------------------------从c中删除迭代器p指定的元素&#xff0c;…

关注BLUEBEE的浏览器发展

其实我并不认识蓝峰这个人。只是偶尔发现这个人在我的博客中转了一下。怀着好奇的心情回访了一下。发现此人正在开发浏览器。目前IE内核的浏览器实在太多了。除了IE本身如遨游&#xff0c;世界之窗&#xff0c;包括360&#xff0c;还有腾讯的TT。。。。。但我为什么要关注蓝峰的…

Ubuntu 9.10 升级到ext4

最近一直在使用ubuntu系统&#xff0c;当时升级到9&#xff0c;04的时候&#xff0c;也没有在意系统的文件系统变了&#xff1b;当使用一段时间之后&#xff0c;发现系统没有8.10时使用的顺畅&#xff0c;这时才发现9.04之后心内核都支持ext4文件系统&#xff0c;该文件系统要比…

史上最简单的软件破解——5行脚本代码完美破解99%的过期软件

如果你看到了这篇博文&#xff0c;绝对保证不虚此行。仅仅5行脚本代码&#xff0c;即可破解99%的过期软件。 这件事的背景&#xff1a;最近在找了一些学习资料&#xff0c;其中有Rational Rose画的图&#xff0c;好久没用过它了。今天安装好&#xff0c;导入许可文件&#xff…

Jquery getJSON方法分析(二)

getJSON与aspx准备工作Customer类publicclassCustomer{ publicintUnid { get; set; } publicstringCustomerName { get; set; } publicstringMemo { get; set; } publicstringOther { get; set; }}&#xff08;一&#xff09;ashxCustomer customer newCustomer …

自适应阈值算法(大津阈值法)

最大类间方差法是由日本学者大津于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU。它是按图像的灰度特性,将图像分成背景和目标2部分。背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部分差…

数据在链路层传播相关时间计算

本来很懵逼的 看到这篇文章基本全懂了 一般这种题目会让我感觉很是煎熬&#xff0c;不知道怎么算。终于打通这类题目&#xff0c;总结到这里。 先看这类题目的常见表述&#xff1a;如图所示&#xff0c;图中路由器采用存储–转发的方式&#xff0c;所有链路的传播速率均为100…

多年以后重发:多线程安全的变量模板

大家好&#xff0c;这里是我以xghome这个用户名&#xff0c;02年在CSDN上发布的《多线程安全的变量模板》&#xff0c;这次在《0bug -- C/C商用工程之道》一书中&#xff0c;作为“资源锁”和多线程通信核心示例&#xff0c;也再次出现。这个模板我当初大约写了19遍&#xff0c…

高等数学的函数连续,可导,可微和偏导数连续的关系(多元)

最近在自学机器学习 顺便把高数捡回来 结论&#xff08;一元函数范畴内&#xff09; 可导与连续的关系&#xff1a;可导必连续&#xff0c;连续不一定可导&#xff1b; 可微与连续的关系&#xff1a;可微与可导是一样的&#xff1b; 可积与连续的关系&#xff1a;可积不一定连续…

也说 ASP.NET MVC的 Script 管理

WebForm下的ScriptManager在ASP.NET MVC下自然是不能使用的。于是很多人开始困惑如何管理页面上可能发生冲突的脚本。CodePlex上还有一个项目专门做这件事情&#xff0c;当然也有人简单地通过HtmlHelper来解决。如果你看过jQuery UI Extensions for ASP.NET MVC&#xff0c;或者…

在控制台中实现“单词竞猜”游戏 C# 猜词游戏

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/u011528448/article/details/24670471 </div><link rel"stylesheet" href"https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_v…

byvoid 神牛的tarjan算法讲解!

[有向图强连通分量] 在有向图G中&#xff0c;如果两个顶点间至少存在一条路径&#xff0c;称两个顶点强连通 (strongly connected)。如果有向图G的每两个顶点都强连通&#xff0c;称G是一个强连通图 。非强连通图有向图的极大强连通子图&#xff0c;称为强连通分量 (strongly …

在Linux下快速搭建LAMP开发平台.doc

1.安装环境操作系统&#xff1a;Red Hat Linux Enterprise AS 4.0 update4数据库&#xff1a;MySQL 5.0.27Web服务器&#xff1a;Apache 2.2.4脚本语言&#xff1a;PHP 5.2.1<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />2.安…

关于NLP你还不会却必须要学会的事儿—NLP实践教程指南第一编

作者 | Dipanjan (DJ) Sarkar 编译 | 姗姗 出品 | 人工智能头条&#xff08;公众号ID&#xff1a;AI_Thinker&#xff09; 【人工智能头条导读】在研究和处理自然语言处理的很多问题时&#xff0c;除了关注各种各样基础的数据&#xff0c;高级的深度学习模型、算法外&#x…

ORACLE中表死锁的处理

在进行数据库管理的过程中,经常会出现数据表被用户的一些不合理操作而导致表被锁定的情况,以下主要介绍如何查找哪些表被哪个用户所锁定,以及如何解除锁定: 1.查找被锁定的表: select object_name,session_id,os_user_name,oracle_username,process,locked_mode,status from v$…