C#编程总结(一)序列化总结_C#教程

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

几种序列化技术:

1)二进制序列化保持类型保真度,这对于在应用程序的不同调用之间保留对象的状态很有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等等。远程处理使用序列化“通过值”在计算机或应用程序域之间传递对象。

2)XML 序列化仅序列化公共属性和字段,且不保持类型保真度。当您要提供或使用数据而不限制使用该数据的应用程序时,这一点是很有用的。由于 XML 是一个开放式标准,因此,对于通过 Web 共享数据而言,这是一个很好的选择。SOAP 同样是一个开放式标准,这使它也成为一个颇具吸引力的选择。

3)使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档(或者JSON格式)。常应用于WCF通信。

BinaryFormatter

序列化可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本。

1、使一个类可序列化的最简单方式是按如下所示使用 Serializable 属性标记。

2、有选择的序列化

通过用 NonSerialized 属性标记成员变量,可以防止它们被序列化

3、自定义序列化

1) 在序列化期间和之后运行自定义方法

最佳做法也是最简单的方法(在 .Net Framework 2.0 版中引入),就是在序列化期间和之后将下列属性应用于用于更正数据的方法:

  • OnDeserializedAttribute
  • OnDeserializingAttribute
  • OnSerializedAttribute
  • OnSerializingAttribute

具体事例如下:

// This is the object that will be serialized and deserialized.
[Serializable()]
public class TestSimpleObject
{
  // This member is serialized and deserialized with no change.
  public int member1;

  // The value of this field is set and reset during and
  // after serialization.
  private string member2;

  // This field is not serialized. The OnDeserializedAttribute
  // is used to set the member value after serialization.
  [NonSerialized()]
  public string member3; 

  // This field is set to null, but populated after deserialization.
  private string member4;

  // Constructor for the class.
  public TestSimpleObject()
  {
    member1 = 11;
    member2 = "Hello World!";
    member3 = "This is a nonserialized value";
    member4 = null;
  }

  public void Print()
  {
    Console.WriteLine("member1 = '{0}'", member1);
    Console.WriteLine("member2 = '{0}'", member2);
    Console.WriteLine("member3 = '{0}'", member3);
    Console.WriteLine("member4 = '{0}'", member4);
  }

  [OnSerializing()]
  internal void OnSerializingMethod(StreamingContext context)
  {
    member2 = "This value went into the data file during serialization.";
  }

  [OnSerialized()]
  internal void OnSerializedMethod(StreamingContext context)
  {
    member2 = "This value was reset after serialization.";
  }

  [OnDeserializing()]
  internal void OnDeserializingMethod(StreamingContext context)
  {
    member3 = "This value was set during deserialization";
  }

  [OnDeserialized()]
  internal void OnDeserializedMethod(StreamingContext context)
  {
    member4 = "This value was set after deserialization.";
  }
}

2) 实现 ISerializable 接口

对于用 Serializable 属性标记且在类级别上或其构造函数上具有声明性或命令性安全的类,不应使用默认序列化。相反,这些类应始终实现 ISerializable 接口。实现 ISerializable 涉及实现 GetObjectData 方法以及在反序列化对象时使用的特殊构造函数。

具体实例如下:

[Serializable]
public class MyObject : ISerializable
{
 public int n1;
 public int n2;
 public String str;

 public MyObject()
 {
 }

 protected MyObject(SerializationInfo info, StreamingContext context)
 {
  n1 = info.GetInt32("i");
  n2 = info.GetInt32("j");
  str = info.GetString("k");
 }
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter
=true)]
 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
 {
  info.AddValue("i", n1);
  info.AddValue("j", n2);
  info.AddValue("k", str);
 }
}

注意:

在反序列化一个对象时不调用构造函数。出于性能方面的原因对反序列化施加了该约束。但是,这违反了运行库与对象编写器之间的一些通常约定,开发人员应确保他们在将对象标记为可序列化时了解其后果。

SoapFormatter

 以 SOAP 格式将对象或整个连接对象的图形序列化和反序列化。基本用法类似于BinaryFormatter。SoapFormatter 和 BinaryFormatter 两个类实现 IRemotingFormatter 接口以支持远程过程调用 (RPC),实现 IFormatter 接口(由 IRemotingFormatter 继承)以支持对象图形的序列化。SoapFormatter 类还支持对 ISoapMessage 对象进行 RPC,而不必使用 IRemotingFormatter 功能。

XmlSerializer

将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。

XML 序列化是将对象的公共属性 (Property) 和字段转换为序列格式(这里是指 XML)以便存储或传输的过程。反序列化则是从 XML 输出中重新创建原始状态的对象。因此,可以将序列化视为将对象的状态保存到流或缓冲区的方法。例如,ASP.NET 使用 XmlSerializer 类对 XML Web services 消息进行编码。

例子:

C#代码

public class MyClass
{
  public MyObject MyObjectProperty;
}
public class MyObject
{
  public string ObjectName;
}

序列化后的XML  

<MyClass>
 <MyObjectProperty>
 <ObjectName>My String</ObjectName>
 </MyObjectProperty>
</MyClass>

还可以通过标记来控制XML的输出

1、默认值

DefaultValueAttribute

2、过滤某属性或字段

XmlIgnoreAttribute

3、重写默认序列化逻辑

具体可见:http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlattributeoverrides(v=vs.80).aspx

其他控制手段,具体可见http://msdn.microsoft.com/zh-cn/library/83y7df3e(v=vs.80).aspx

4、将对象序列化为 SOAP 编码的 XML 流

http://msdn.microsoft.com/zh-cn/library/bd04skah(v=vs.80).aspx

注意

XML 序列化不转换方法、索引器、私有字段或只读属性(只读集合除外)。要序列化对象的所有字段和属性(公共的和私有的),请使用 BinaryFormatter,而不要使用 XML 序列化。

DataContractSerializer

使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档。 此类不能被继承。

DataContractSerializer 用于序列化和反序列化在 Windows Communication Foundation (WCF) 消息中发送的数据。 通过将 DataContractAttribute 属性 (Attribute) 应用于类,而将 DataMemberAttribute 属性 (Attribute) 应用于类成员,可以指定要序列化的属性 (Property) 和字段。

使用步骤:

1)DataContractSerializer 与 DataContractAttribute 和 DataMemberAttribute 类结合使用。

要准备序列化某个类,请将 DataContractAttribute 应用于该类。 对于返回要序列化的数据的类的每个成员,请应用 DataMemberAttribute。 您可以序列化字段和属性,而无论其可访问性级别是什么:private、protected、internal、protected internal 或 public。

2)添加到已知类型的集合中

在序列化或反序列化对象时,DataContractSerializer 必须“已知”该类型。 首先,创建一个实现 IEnumerable<T>(如 List<T>)的类实例,并将已知类型添加到集合中。 然后,使用接受 IEnumerable<T>(例如,[M:System.Runtime.Serialization.DataContractSerializer.#ctor(System.Type,System.Collections.Generic.IEnumerable{System.Type}])的重载之一创建 DataContractSerializer 的实例。

具体实例:

namespace DataContractSerializerExample
{
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Runtime.Serialization;
  using System.Xml;

  // You must apply a DataContractAttribute or SerializableAttribute
  // to a class to have it serialized by the DataContractSerializer.
  [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")]
  class Person : IExtensibleDataObject
  {
    [DataMember()]
    public string FirstName;
    [DataMember]
    public string LastName;
    [DataMember()]
    public int ID;

    public Person(string newfName, string newLName, int newID)
    {
      FirstName = newfName;
      LastName = newLName;
      ID = newID;
    }

    private ExtensionDataObject extensionData_Value;

    public ExtensionDataObject ExtensionData
    {
      get
      {
        return extensionData_Value;
      }
      set
      {
        extensionData_Value = value;
      }
    }
  }

  public sealed class Test
  {
    private Test() { }

    public static void Main()
    {
      try
      {
        WriteObject("DataContractSerializerExample.xml");
        ReadObject("DataContractSerializerExample.xml");

      }

      catch (SerializationException serExc)
      {
        Console.WriteLine("Serialization Failed");
        Console.WriteLine(serExc.Message);
      }
      catch (Exception exc)
      {
        Console.WriteLine(
        "The serialization operation failed: {0} StackTrace: {1}",
        exc.Message, exc.StackTrace);
      }

      finally
      {
        Console.WriteLine("Press <Enter> to exit....");
        Console.ReadLine();
      }
    }

    public static void WriteObject(string fileName)
    {
      Console.WriteLine(
        "Creating a Person object and serializing it.");
      Person p1 = new Person("Zighetti", "Barbara", 101);
      FileStream writer = new FileStream(fileName, FileMode.Create);
      DataContractSerializer ser =
        new DataContractSerializer(typeof(Person));
      ser.WriteObject(writer, p1);
      writer.Close();
    }

    public static void ReadObject(string fileName)
    {
      Console.WriteLine("Deserializing an instance of the object.");
      FileStream fs = new FileStream(fileName,
      FileMode.Open);
      XmlDictionaryReader reader =
        XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
      DataContractSerializer ser = new DataContractSerializer(typeof(Person));

      // Deserialize the data and read it from the instance.
      Person deserializedPerson =
        (Person)ser.ReadObject(reader, true);
      reader.Close();
      fs.Close();
      Console.WriteLine(String.Format("{0} {1}, ID: {2}",
      deserializedPerson.FirstName, deserializedPerson.LastName,
      deserializedPerson.ID));
    }
  }

DataContractJsonSerializer

将对象序列化为 JavaScript 对象表示法 (JSON),并将 JSON 数据反序列化为对象。 此类不能被继承。

具体使用与DataContractSerializer类似。这里不再赘述。

下面对这些方法的使用做了汇总,希望能给大家带来一些帮助。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;

namespace SerializerSample
{
  /// <summary>
  /// 序列化帮助类
  /// </summary>
  public sealed class SerializeHelper
  {
    #region DataContract序列化
    /// <summary>
    /// DataContract序列化
    /// </summary>
    /// <param name="value"></param>
    /// <param name="knownTypes"></param>
    /// <returns></returns>
    public static string SerializeDataContract(object value, List<Type> knownTypes = null)
    {
      DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType(), knownTypes);

      using (MemoryStream ms = new MemoryStream())
      {
        dataContractSerializer.WriteObject(ms, value);
        ms.Seek(0, SeekOrigin.Begin);
        using (StreamReader sr = new StreamReader(ms))
        {
          return sr.ReadToEnd();
        }
      }
    }
    /// <summary>
    /// DataContract反序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="xml"></param>
    /// <returns></returns>
    public static T DeserializeDataContract<T>(string xml)
    {
      using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
      {
        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
        return (T)serializer.ReadObject(ms);
      }
    }
    #endregion

    #region DataContractJson序列化
    /// <summary>
    /// DataContractJson序列化
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static string SerializeDataContractJson(object value)
    {
      DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(value.GetType());
      using (MemoryStream ms = new MemoryStream())
      {
        dataContractSerializer.WriteObject(ms, value);
        return Encoding.UTF8.GetString(ms.ToArray());
      }
    }
    /// <summary>
    /// DataContractJson反序列化
    /// </summary>
    /// <param name="type"></param>
    /// <param name="str"></param>
    /// <returns></returns>
    public static object DeserializeDataContractJson(Type type, string str)
    {
      DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(type);
      using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str)))
      {
        return dataContractSerializer.ReadObject(ms);
      }
    }
    /// <summary>
    /// DataContractJson反序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="json"></param>
    /// <returns></returns>
    public T DeserializeDataContractJson<T>(string json)
    {
      DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(typeof(T));
      using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
      {
        return (T)dataContractSerializer.ReadObject(ms);
      }
    }
    #endregion

    #region XmlSerializer序列化
    /// <summary>
    /// 将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static string SerializeXml(object value)
    {
      XmlSerializer serializer = new XmlSerializer(value.GetType());
      using (MemoryStream ms = new MemoryStream())
      {
        serializer.Serialize(ms, value);
        ms.Seek(0, SeekOrigin.Begin);
        using (StreamReader sr = new StreamReader(ms))
        {
          return sr.ReadToEnd();
        }
      }
    }
    /// <summary>
    /// XmlSerializer反序列化
    /// </summary>
    /// <param name="type"></param>
    /// <param name="str"></param>
    /// <returns></returns>
    public static object DeserializeXml(Type type, string str)
    {
      XmlSerializer serializer = new XmlSerializer(type);
      byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
      using (MemoryStream ms = new MemoryStream(bytes))
      {
        return serializer.Deserialize(ms);
      }
    }
    #endregion

    #region BinaryFormatter序列化
    /// <summary>
    /// BinaryFormatter序列化
    /// 必须类型必须标记为Serializable
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string SerializeBinaryFormatter(object obj)
    {
      BinaryFormatter formatter = new BinaryFormatter();
      using (MemoryStream ms = new MemoryStream())
      {
        formatter.Serialize(ms,obj);
        byte[] bytes = ms.ToArray();
        obj = formatter.Deserialize(new MemoryStream(bytes));
        //如果是UTF8格式,则反序列化报错。可以用Default格式,不过,建议还是传参为byte数组比较好
        return Encoding.Default.GetString(bytes);
      }
    }

    /// <summary>
    /// BinaryFormatter反序列化
    /// 必须类型必须标记为Serializable
    /// </summary>
    /// <param name="serializedStr"></param>
    /// <returns></returns>
    public static T DeserializeBinaryFormatter<T>(string serializedStr)
    {
      BinaryFormatter formatter = new BinaryFormatter();
      byte[] bytes = Encoding.Default.GetBytes(serializedStr);
      using (MemoryStream ms = new MemoryStream(bytes))
      {
        return (T)formatter.Deserialize(ms);
      }
    }
    #endregion 

    #region SoapFormatter序列化
    /// <summary>
    /// SoapFormatter序列化
    /// 必须类型必须标记为Serializable
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string SerializeSoapFormatter(object obj)
    {
      SoapFormatter formatter = new SoapFormatter();
      using (MemoryStream ms = new MemoryStream())
      {
        formatter.Serialize(ms, obj);
        byte[] bytes = ms.ToArray();
        return Encoding.UTF8.GetString(bytes);
      }
    }
    /// <summary>
    /// SoapFormatter反序列化
    /// 必须类型必须标记为Serializable
    /// </summary>
    /// <param name="serializedStr"></param>
    /// <returns></returns>
    public static T DeserializeSoapFormatter<T>(string serializedStr)
    {
      SoapFormatter formatter = new SoapFormatter();
      using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serializedStr)))
      {
        return (T)formatter.Deserialize(ms);
      }
    }
    #endregion
  }
}

具体的实例代码如下:

下载:demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索xml
, c#
, 序列化
对象序列化为xml
c站、c语言、cf、ch、c罗,以便于您获取更多的相关知识。

时间: 2024-09-29 05:17:12

C#编程总结(一)序列化总结_C#教程的相关文章

.Net WInform开发笔记(三)谈谈自制控件(自定义控件)_C#教程

末日这天写篇博客吧,既然没来,那就纪念一下. 这次谈谈自制控件,也就是自定义控件,先上图,再说 1.扩展OpenFileDialog,在OpenFileDialog中添加各种文件(.txt,.jpg,.excel等等)的预览功能 开发笔记(三)谈谈自制控件(自定义控件)_C#教程-winform自定义控件"> 2.重写ListBox,增加折叠.鼠标背影.分类等功能 -----------------------------分割线-------------------------------

.Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用_C#教程

中午没事,把去年刚毕业那会画的几张图翻出来了,大概介绍Winform应用程序运行的过程,以及TCP协议在Winform中的应用.如果有Windows消息机制等基础,很好理解这两张图. (1)Winform应用程序运行结构图 开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用_C#教程-tcp ip协议 层结构图"> (2)TCP通讯协议在Winform程序中的应用示意图 熟悉整个程序的来龙去脉,编程的时候就会很轻松,不会云里雾里. 另附公司招聘面试题一份,用了几

Lua编程中使用嵌套循环的使用教程

  这篇文章主要介绍了Lua编程中使用嵌套循环的使用教程,是Lua入门学习中的基础知识,需要的朋友可以参考下 Lua编程语言允许使用一个循环内嵌另一个循环.下文将介绍几个例子来说明这一概念. 语法 在Lua中嵌套循环语法语句如下: 代码如下: for init,max/min value, increment do for init,max/min value, increment do statement(s) end statement(s) end 在Lua编程语言中的嵌套的while循环

使用VS2010 C#开发ActiveX控件(下),完整代码打包下载_C#教程

其实如果我们不进行设置,只是修改了代码,运行程序以后,其出错界面如下图1所示: 开发ActiveX控件(下),完整代码打包下载_C#教程-vs2010使用教程 c"> 图1 抛出异常如下: ************** Exception Text ************** System.MethodAccessException: Attempt by security transparent method 'Rare.Card.Libary.Controls. ReadCardCo

详解state状态模式及在C++设计模式编程中的使用实例_C 语言

每个人.事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State).最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你通过.在出口处也是验票,如果正确你就可以 ok,否则就不让你通过(如果你动作野蛮,或许会有报警(Alarm),:)). 有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移). 通常我们在实现这类系统会使用到很多的 Switch/Case 语句,Case 某种状态,发生什么动作,C

C#.net编程创建Access文件和Excel文件的方法详解_C#教程

本文实例讲述了C#.net编程创建Access文件和Excel文件的方法.分享给大家供大家参考,具体如下: 一些系统可能需求把数据导出到Access或者Excel文件格式,以方便的传递数据.打印等. Excel 文件或者 Access这两种需要导出的文件可能并不是事先就存在的,这就需要我们自己编程生成他们,下面整理一下生成这两个文件的一些方法,只罗列最常用的.并不全. 一.首先生成Excel文件. 方案一.如果用Excel保存的只是二维数据,也就是把他当数据库的来用. 最简单,你不用引用任何额外

C#实现XML与实体类之间相互转换的方法(序列化与反序列化)_C#教程

本文实例讲述了C#实现XML与实体类之间相互转换的方法.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Xml; using System.Xml.Serialization; /// <summary> /// Xml序列化与反序列化 //

C# XML序列化方法及常用特性总结分析_C#教程

本文实例总结了C# XML序列化方法及常用特性.分享给大家供大家参考,具体如下: C#对象XML序列化(一):序列化方法和常用特性 .Net Framework提供了对应的System.Xml.Seriazliation.XmlSerializer负责把对象序列化到XML,和从XML中反序列化为对象.Serializer的使用比较直观,需要多注意的是XML序列化相关的Attribute,怎么把这些attribute应用到我们的对象,以及对象公共属性上面去,生成满足预期格式的XML. 这里列出了最

C#编程实现动态改变配置文件信息的方法_C#教程

本文实例讲述了C#编程实现动态改变配置文件信息的方法.分享给大家供大家参考,具体如下: 配置文件实际上就是一个XML文件,所以我们可以使用XmlDocument来进行操作. 代码如下: static void Main(string[] args) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("../../App.config");//加载xml文件 XmlNode xNode; XmlElement xElem1; XmlEle