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

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

 代码:/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,一经查实,立即删除!

相关文章

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

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

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…

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

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

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

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

在控制台中实现“单词竞猜”游戏 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 …

关于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$…

asp.net文件上传进度条控件(破解版~没有时间限制) 多项自定义

原版只能用30天&#xff0c;这个破解版可以长期用了&#xff08;设置了时间2010-2110&#xff09;. 注册控件&#xff1a;<% Register TagPrefix"fup" Namespace"OboutInc.FileUpload" Assembly"FileUpload" %>调用控件&#xff1a;<fo…

矩阵连乘问题的算法分析

问题描述&#xff1a;给定n个矩阵&#xff1a;A1,A2,...,An&#xff0c;其中Ai与Ai1是可乘的&#xff0c;i1&#xff0c;2...&#xff0c;n-1。确定计算矩阵连乘积的计算次序&#xff0c;使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模&…

等一分钟看了会流泪

转载于:https://blog.51cto.com/hljheiwangwei/269127

Silverlight 解谜游戏 之十六 消失的蒙娜丽莎

在《Silverlight 解谜游戏 之三 消除名单》中我们通过在物品轮廓画出Path 来达到消除物品的效果&#xff0c;由于游戏中的物品都是Office 图片的一部分所以无法使其真正消失&#xff0c;本篇我们将添加一个独立于Office 图片的物品&#xff0c;使其能动态消失。 看看题板上多出…

明令禁止工作“996”,是对“生而为人”的基本尊重

离GitHub上996.ICU项目的发布时间已过去好一段时间了&#xff0c;作为一名计算机专业的在读生&#xff0c;对996有一点体会&#xff0c;最直观的体会就是为了提升技术&#xff0c;连续一个学期在实验室工作超过10个小时。 人民日报发文《被“996”围困的年轻人&#xff0c;像是…

让sky Driver成为你的可见硬盘

网盘就不用多说了&#xff0c;国内国外的都很多&#xff0c;但是sky Driver以25G的大容量还是吸引着我&#xff0c;看来还是盖茨比较称钱&#xff08;sorry&#xff0c;方言&#xff0c;意思就是nb的意思&#xff09;&#xff0c;但是一向以用户体验非常不错著称的microsoft在这…

设计模式----Adapter(适配器)

作用: 将一个类的接口转换成客户希望的另外一个接口。Adapt 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 UML示意图 1)采用继承原有接口类的方式 2)采用组合原有接口类的方式 解析: Adapt模式其实就是把完成同样的一个功能但是接口不能兼容的类桥接在一起…

Exchange 2003升级至Exchange 2007

环境: 三台机器:DC Exchange2003 Exchange2007 计算机名:DC MAIL NEWMAIL 前提条件: 1.Exchange组织设置为纯模式。 2.Exchange 2003安装SP2 3.拥有Schema Master角色的DC及所有GC运行在Windows 2003 SP1或更高以上 4.AD域提升到最高 不被Exchange 2007支持的组件有: Nov…

蓝桥杯 标题:纵横火柴旗子

【编程题】这是一个纵横火柴棒游戏。如图[1.jpg]&#xff0c;在一个3x4的方格中&#xff0c;游戏的双方轮流放置火柴棒。其规则是&#xff1a;1. 不能放置在已经放置火柴棒的地方&#xff08;即只能在空格中放置&#xff09;。2. 火柴棒的方向只能是垂直或水平放置。3. 火柴棒不…

易语言源代码毁来者来了!!

2009年12月7号16:34分&#xff0c;恐怖现象在次出现了&#xff01; 在编译易程序时&#xff0c;突然提示&#xff0c;某某模块找不到了&#xff0c;我跑到软件目录下一看&#xff0c;妈啊不得了&#xff0c;目录中一百多个文件能删除的全部都被删除了&#xff0c;只剩余几个残破…

矩阵连乘 动态规划 详解

矩阵连乘问题----动态规划(转载)&#xff1a; 给定n个矩阵&#xff5b;A1,A2,…,An&#xff5d;&#xff0c;其中Ai与Ai1是可乘的&#xff0c;i1&#xff0c;2…&#xff0c;n-1。如何确定计算矩阵连乘积的计算次序&#xff0c;使得依此次序计算矩阵连乘积需要的数乘次数最少。…