C# serializable

Serializable 序列化

含义

序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

目的

  1. 以某种存储形式使自定义对象持久化
  2. 将对象从一个地方转移到另一个地方
  3. 使程序更具维护性

技术

二进制序列化保持类型保真度,这对于在应用程序的不同调用之间保留对象的状态很有用。例如,通过将对象序列化到剪贴板,可在不同应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等等。远程处理使用序列化“通过值”在计算机或应用程序域之间传递对象。
XML序列化仅序列化公共属性和字段,且不保持类型保真度。当您要提供或使用数据而不限制使用该数据的应用程序时,这一点是很有用的。由于XML是一个开放式标准,因此,对于通过Web共享数据而言,这是一个很好的选择。SOAP同样是一个开放式标准。这使它成为一个颇具吸引力的选择。 原文链接

将对象序列化到剪切板
public interface ISerializer
{
    byte[] ToBinary(object obj);

    string ToString(object obj);

    T ToObject<T>(byte[] data);

    T ToObject<T>(string dataString);

    T Copy<T>(T obj);
}

public class XmlSerializer : ISerializer
{
     public byte[] ToBinary(object obj)
     {
         using (MemoryStream fs = new MemoryStream())
         {
             System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(obj.GetType());
             x.Serialize(fs, obj);
             return fs.ToArray();
         }
     }


     public T ToObject<T>(byte[] data)
     {
         using (MemoryStream sr = new MemoryStream(data))
         {
             System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T));
             return (T)(x.Deserialize(sr));
         }
     }

     public string ToString(object obj)
     {
         return Encoding.UTF8.GetString(ToBinary(obj));
     }

     public T ToObject<T>(string dataString)
     {
         return ToObject<T>(Encoding.UTF8.GetBytes(dataString));
     }

     public object ToObject(Type t, string dataString)
     {
         var data = Encoding.UTF8.GetBytes(dataString);

         using (MemoryStream sr = new MemoryStream(data))
         {
             System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(t);
             return x.Deserialize(sr);
         }
     }

     public T Copy<T>(T obj)
     {
         return ToObject<T>(ToBinary(obj));
     }
 }

//使用方法
SortedList<int, Param> sortedParams = new SortedList<int, Param>();
//给sortedParams中添加数据,Param为自定义对象
ISerializer serializer = new XmlSerializer();
var vvv = serializer.ToString(sortedParams.Values.ToList());
Clipboard.SetData("TMC", vvv);

其中Clipboard类提供可以方便地与系统剪切板相互传输数据的静态方法。
在这里插入图片描述
在这里插入图片描述

将剪切板中的数据反序列化为可操作的对象
var formats = Clipboard.GetDataObject().GetFormats();

if (formats.Length == 1 && formats[0] == "TMC") // 此状态下为系统内部拷贝
{
    var paramsStr = Clipboard.GetData("TMC").ToString();

    ISerializer serializer = new XmlSerializer();
    var pasteParams = serializer.ToObject<List<Param>>(paramsStr);
}
处理从外部复制的数据
/// <summary>
/// 获取剪切板中的数据
/// </summary>
private List<List<string>> GetRtfDatas()
{
    List<List<string>> datas = new List<List<string>>();

    IDataObject ido = Clipboard.GetDataObject();
    if (ido.GetDataPresent(DataFormats.Rtf))
    {
        string rtf = (string)ido.GetData(DataFormats.Rtf);
        RTFDomDocument doc = new RTFDomDocument();
        doc.LoadRTFText(rtf);

        foreach (RTFDomElement element in doc.Elements)
        {
            if (element is RTFDomTable)
            {
                var table = element as RTFDomTable;

                if (table.Elements.Count <= 0)
                {
                    return datas;
                }
                else
                {
                    foreach (RTFDomTableRow row in table.Elements)
                    {
                        List<string> rowDatas = new List<string>();

                        foreach (RTFDomTableCell cell in row.Elements)
                        {
                            rowDatas.Add(cell.InnerText);
                        }

                        datas.Add(rowDatas);
                    }
                }
            }
            else
            {
                string text = "";
                foreach (RTFDomElement elementin in doc.Elements)
                {
                    text += elementin.InnerText;
                }
                List<string> rowDatas = new List<string>();
                rowDatas.Add(text);

                datas.Add(rowDatas);
                break;
            }
        }
    }

    return datas;
}

接下来,涉及到的就是XML序列化。

要使一个类可以序列化,可以使用Serializable标签进行标记。

namespace lyy.Model
{
	[Serializable]
	public class Model : NotificationObject
	{
		//名称
		[XmlAttribute("Name")]
		public string Name
		{
			get {return _name;}
			set {_name = value;}
		}
		private string _name = String.Empty;
		
		//IP地址
		[XmlAttribute("IP")]
		public string IP
		{
			get {return _ip;}
			set 
			{
				_ip = value;
				RaisePropertyChanged("IP");
			}
		}
		private string _ip = "127.0.0.1";
		
		//端口号
		[XmlAttribute("Port")]
		public string Port
		{
			get {return _port;}
			set 
			{
				_port = value;
				RaisePropertyChanged("Port");
			}
		}
		private int_port = 0;
	}
}

在上面这段代码中,可以看到涉及到三个部分分别是[Serializable]、继承了抽象类NotificationObject、[XmlAttribute(“xxx”)]和RaisePropertyChanged(“xxx”)。
.NET 支持对象xml序列化和反序列化的类库主要位于命名空间System.Xml.Serialization中。

  1. XmlSerializer 类
    该类用一种高度松散耦合的方式提供串行化服务。你的类不需要继承特别的基类,而且它们也不需要实现特别的接口。相反,你只需在你的类或者这些类的公共域以及读/写属性里加上自定义的特性。XmlSerializer通过反射机制读取这些特性并用它们将你的类和类成员映射到xml元素和属性。该类可以将指定类型的对象序列化为XML文档,也可以将XML文档反序列化为指定类型的对象。
  2. XmlAttributeAttribute 类
    指定类的公共域或读/写属性对应xml文件的Attribute。
    例:[XmlAttribute(“type”)] or [XmlAttribute(AttributeName=”type”)]
  3. XmlElementAttribute类
    指定类的公共域或读/写属性对应xml文件的Element。
    例:[XmlElement(“Maufacturer”)] or [XmlElement(ElementName=”Manufacturer”)]
  4. XmlRootAttribute类
    Xml序列化时,由该特性指定的元素将被序列化成xml的根元素。
    例:[XmlRoot(“RootElement”)] or [XmlRoot(ElementName = “RootElements”)]
  5. XmlTextAttribute 类
    Xml序列化时,由该特性指定的元素值将被序列化成xml元素的值。一个类只允许拥有一个该特性类的实例,因为xml元素只能有一个值。
  6. XmlIgnoreAttribute类
    Xml序列化时不会序列化该特性指定的元素。
public static bool ReaderXml<T>(string name,ref T obj)
{
    string path = name;
    if(File.Exists(path))
    {
        using(var textReader = new XmlTextReader(path))
        {
            try
            {
                var deserialize = new XmlSerializer(typeof(T));
                obj = (T)deserialize.Deserialize(textReader);
                return true;
            }
            catch (Exception )
            {
                throw;
            }
        }
    }
}

//读取配置文件
Model _model = new Model();
xx.ReaderXml<Model>(AppDomain.CurrentDomain.BaseDirectory+"xx.xml",ref _model)
//AppDomain.CurrentDomain.BaseDirectory 表示当前应用程序域的基目录
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值