zoukankan      html  css  js  c++  java
  • 编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化

    建议54:为无用字段标注不可序列化

    序列化是指这样一种技术:把对象转变成流。相反过程,我们称为反序列化。在很多场合都需要用到这项技术。

    • 把对象保存到本地,在下次运行程序的时候,恢复这个对象。
    • 把对象传到网络中的另外一台终端上,然后在此终端还原这个对象。
    • 其他场合,如:把对象赋值到系统的粘贴板中,然后用快捷键Ctrl+V恢复这个对象。

    一下几个原因,决定了要为无用字段标注不可序列化:

    1. 节约了空间。类型在序列化后往往会存储到某个地方,如数据库、硬盘或内存中,如果一个字段在反序列化后不需要保持状态,那它就不应该被序列化,这会占用宝贵的空间资源。
    2. 反序列化后字段信息已经没有意义了。如Windows内核句柄,在反序列化后往往已经失去了意义,所以它就不应该被序列化。
    3. 字段因业务上的原因不允许被序列化。比如,明文密码不应该被序列化后一同保存在文件中。
    4. 如果字段本身所对应的类型在代码中未被设定成可序列化,那它就该被标注不可序列化,否则运行时会抛出SerializationException异常。


    类型被添加Serializable特性后,默认所有的字段全部都能被序列化。如果部分字段不需要序列化,可以在该字段上应用NonSerialized特性。属性事实上是方法,所以是不能序列化的,自动属性也是如此。另外,要标识事件为不可序列化,需要用field: NonSerialized语法。

    下面是一个序列化工具类:

        public class BinarySerializer
        {
            //将类型序列化为字符串
            public static string Serialize<T>(T t)
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, t);
                    return System.Text.Encoding.UTF8.GetString(stream.ToArray());
                }
            }
    
            //将类型序列化为文件
            public static void SerializeToFile<T>(T t, string path, string fullName)
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                string fullPath = Path.Combine(path, fullName);
                using (FileStream stream = new FileStream(fullPath, FileMode.OpenOrCreate))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, t);
                    stream.Flush();
                }
            }
    
            //将字符串反序列化为类型
            public static TResult Deserialize<TResult>(string s) where TResult : class
            {
                byte[] bs = System.Text.Encoding.UTF8.GetBytes(s);
                using (MemoryStream stream = new MemoryStream(bs))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    return formatter.Deserialize(stream) as TResult;
                }
            }
    
            //将文件反序列化为类型
            public static TResult DeserializeFromFile<TResult>(string path) where TResult : class
            {
                using (FileStream stream = new FileStream(path, FileMode.Open))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    return formatter.Deserialize(stream) as TResult;
                }
            }
        }

    实例代码:

        class Program
        {
            static void Main()
            {
                Person mike = new Person() { Age = 21, Name = "Mike" };
                mike.NameChanged += new EventHandler(mike_NameChanged);
                BinarySerializer.SerializeToFile(mike, @"c:", "person.txt");
                Person p = BinarySerializer.DeserializeFromFile<Person>(@"c:person.txt");
                p.Name = "Rose";
                Console.WriteLine(p.Name);
                Console.WriteLine(p.Age.ToString());
            }
    
            static void mike_NameChanged(object sender, EventArgs e)
            {
                Console.WriteLine("Name Changed");
            }
        }
    
        [Serializable]
        class Person
        {
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    if (NameChanged != null)
                    {
                        NameChanged(this, null);
                    }
                    name = value;
                }
            }
    
            public int Age { get; set; }
    
            [NonSerialized]
            private Department department;
            public Department Department
            {
                get
                {
                    return department;
                }
                set
                {
                    department = value;
                }
            }
    
            [field: NonSerialized]
            public event EventHandler NameChanged;
        }

    输出:

    Rose
    21

    转自:《编写高质量代码改善C#程序的157个建议》陆敏技

  • 相关阅读:
    第六次实验报告
    第三次实验报告
    第五张循环语句总结
    第二次实验报告
    第一次实验报告
    第一次作业
    第九章 结构体与共用体
    第八章 指针实验
    第七章数组实验
    第六章实验报告(2)
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4735351.html
Copyright © 2011-2022 走看看