码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • C#对象序列化


    C# 对象序列化三种方式

    一、常规序列化方式

    对象标记为可序列化,然后把不需要序列化的字段加上[NonSerialized]特性

    序列化测试对象SerializeTest

    	[Serializable]
        public class SerializeTest
        {
            
            [NonSerialized]
            private string _name;
    
            public SerializeTest(string name, string ip, int port, ITestInfo testInfo)
            {
                Name = name;
                IP = ip;
                Port = port;
                TestInfo = testInfo;
            }
    
            public string Name { get { return _name; } set { _name = value; } }
    
            public string IP { get; set; }
    
            public int Port { get; set; }
    
            public ITestInfo TestInfo { get; set; }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    序列化对象包含的对象接口

        public interface ITestInfo
        {
            string Message { get; set; }
    
            int Id { get; set; }
    
            List InfoList { get; set; }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    序列化对象包含的对象接口实现

        [Serializable]
    	public class TestInfo : ITestInfo
        {
            public TestInfo(string message, int id, List infoList)
            {
                Message = message;
                Id = id;
                InfoList = infoList;
            }
    
            public string Message { get; set; }
            public int Id { get; set; }
            public List InfoList { get; set; }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    然后通过窗体的保存按钮进行对象序列化,加载时反序列化,进行测试,代码如下:

       public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                var serializeTest = SerializeUtils.DeserializeBinaryFromFile("F:\\temp\\test.dat");
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                ITestInfo testInfo = new TestInfo("消息",1,new List { "测试","121"});
                SerializeTest serializeTest = new SerializeTest("序列化测试","127.0.0.1",8080,testInfo);
                SerializeUtils.SerializeBinaryToFile(serializeTest, "F:\\temp\\test.dat");
            }
           
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    序列化工具类

     public class SerializeUtils
        {
            public static object DeserializeBinaryFromFile(string file)
            {
                FileStream fs = null;
                try
                {
                    fs = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
    
                    BinaryFormatter deserializer = new BinaryFormatter();
                    object newobj = deserializer.Deserialize(fs);
    
                    fs.Close();
                    return newobj;
                }
                catch (Exception ex)
                {
                    if (fs != null) fs.Close();
                    return null;
                }
            }
    
            public static bool SerializeBinaryToFile(object request, string file)
            {
                try
                {
                    BinaryFormatter serializer = new BinaryFormatter();
                    FileStream fs = new FileStream(file, FileMode.Create, FileAccess.ReadWrite);
                    serializer.FilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Low;
                    serializer.Serialize(fs, request);
                    fs.Close();
                    return true;
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    测试结果如下:

    点击保存待保存对象截图:
    在这里插入图片描述

    重新启动反序列化结果如下:
    在这里插入图片描述

    Name为null,没有保存
    
    • 1

    二、实现ISerializable接口

    通过实现ISerializable接口的GetObjectData方法,把需要序列化保存的数据通过info.AddValue方法进行添加,此时不需要使用特性 [NonSerialized]
    添加有参构造来实现对象的数据的获取

    将SerializeTest类改造如下

    [Serializable]
    public class SerializeTest : ISerializable
    {
        public SerializeTest(string name, string ip, int port, ITestInfo testInfo)
        {
            Name = name;
            IP = ip;
            Port = port;
            TestInfo = testInfo;
        }
    
        public string Name { get; set; }
    
        public string IP { get; set; }
    
        public int Port { get; set; }
    
        public ITestInfo TestInfo { get; set; }
    
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("IP", this.IP);
            info.AddValue("Port", this.Port);
            info.AddValue("TestInfo", this.TestInfo);
        }
    
        protected SerializeTest(SerializationInfo info, StreamingContext context)
        {
            try
            {
                SerializationInfoEnumerator enumerator = info.GetEnumerator();
                this.IP = GetValueBySerializationInfo(info, "IP");
                this.Port = GetValueBySerializationInfo(info, "Port");
                while (enumerator.MoveNext())
                {
                    if (enumerator.Name == "TestInfo") this.TestInfo = (ITestInfo)enumerator.Value;
                }
            }
            catch (Exception e)
            {
            }
        }
    
        /// 
        /// 根据key从序列化对象获取值
        /// 
        /// 
        /// 
        /// 
        /// 
        public T GetValueBySerializationInfo(SerializationInfo info, string key)
        {
            try
            {
                return (T)info.GetValue(key, typeof(T));
            }
            catch
            {
                return default(T);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    删除test.dat文件重新测试,测试结果一致。

    三、通过反射方式

    在方式二的基础上通过反射自动将需要序列化的数据进行保存和获取,注意此方式将不需要序列化的属性使用特性[XmlIgnore]标记,对于需要序列化的属性较多时效果较好,SerializeTest类改造如下:

    [Serializable]
    public class SerializeTest : ISerializable
    {
        public SerializeTest(string name, string ip, int port, ITestInfo testInfo)
        {
            Name = name;
            IP = ip;
            Port = port;
            TestInfo = testInfo;
            TestInfo = testInfo;
        }
        [XmlIgnore]
        public string Name { get; set; }
    
        public string IP { get; set; }
    
        public int Port { get; set; }
        public ITestInfo TestInfo { get; set; }
    
    
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            var properties = GetProperties();
            foreach (var property in properties)
            {
                if (IsNeedSerializedProperty(property))
                {
                    info.AddValue(property.Name, GetPropertyValue(property));
                }
            }
        }
    
        protected SerializeTest(SerializationInfo info, StreamingContext context)
        {
            try
            {
                var properties = GetProperties();
                foreach (var property in properties)
                {
                    if (IsNeedSerializedProperty(property))
                    {
                        try
                        {
                            SetPropertyValue(property, GetValueBySerializationInfo(info, property.Name));
                        }
                        catch (Exception ex)
                        {
    
                        }
                    }
                }
            }
            catch (Exception e)
            {
            }
        }
        private PropertyInfo[] GetProperties()
        {
            return this.GetType().GetProperties();
        }
        /// 
        /// 属性是否可序列化
        /// 
        /// 
        /// 
        private bool IsNeedSerializedProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null) return false;
            return propertyInfo.GetCustomAttribute(typeof(XmlIgnoreAttribute)) == null
                    && propertyInfo.CanWrite;
        }
        private object GetPropertyValue(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null) return null;
            return this.GetType().GetProperty(propertyInfo.Name).GetValue(this, null);
        }
        private void SetPropertyValue(PropertyInfo propertyInfo, object value)
        {
            if (propertyInfo == null) return;
            this.GetType().GetProperty(propertyInfo.Name).SetValue(this, value);
        }
        /// 
        /// 根据key从序列化对象获取值
        /// 
        /// 
        /// 
        /// 
        /// 
        public T GetValueBySerializationInfo(SerializationInfo info, string key)
        {
            try
            {
                return (T)info.GetValue(key, typeof(T));
            }
            catch
            {
                return default(T);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    删除test.dat文件重新测试,测试结果一致。

  • 相关阅读:
    字符串匹配算法:KMP
    机器人中的数值优化(十一)——高斯牛顿法、LMF方法、Dogleg方法
    自然语言处理 Paddle NLP - 快递单信息抽取 (ERNIE 1.0)
    zookeeper动态扩缩容(无需重启)
    线性代数2:梯队矩阵形式
    利用熵权法进行数值评分计算——算法过程
    C 语言文件操作函数大全 (超详细)
    【SQL】SQL语句执行顺序
    网络问题排障专题-AF网络问题排障
    *Django中的Ajax jq的书写样式1
  • 原文地址:https://blog.csdn.net/abcwanglinyong/article/details/126662733
    • 最新文章
    • 攻防演习之三天拿下官网站群
      数据安全治理学习——前期安全规划和安全管理体系建设
      企业安全 | 企业内一次钓鱼演练准备过程
      内网渗透测试 | Kerberos协议及其部分攻击手法
      0day的产生 | 不懂代码的"代码审计"
      安装scrcpy-client模块av模块异常,环境问题解决方案
      leetcode hot100【LeetCode 279. 完全平方数】java实现
      OpenWrt下安装Mosquitto
      AnatoMask论文汇总
      【AI日记】24.11.01 LangChain、openai api和github copilot
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
    正则表达式工具 cron表达式工具 密码生成工具

    京公网安备 11010502049817号