序列化相关:实现ISerializable后序列化用没用到反射?

xiaojunjor 2018-03-15 01:59:04
我在看《CLR via C#》里面提到默认的序列化是使用反射实现的,可以通过实现ISerializable接口避免使用反射来序列化

我查了一下源码,发现确实如果实现了ISerializable,就没有调用默认的序列化方法


如果按照这个思想,就是说ISerializable.GetObjectData中SerializationInfo没有AddValue的数据都不会被序列化保存。简单写了个代码测试


[Serializable()]
class A : ISerializable
{
public string str = "abc";
public int i = 10;

public A()
{

}

public A(SerializationInfo info, StreamingContext context)
{
this.i = info.GetInt32("i");
}

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("i", 10);
}
}

class Demo
{
public static void Main(String[] args)
{
MemoryStream stream = new MemoryStream();
var formatter = new BinaryFormatter();
A a = new A();
formatter.Serialize(stream, a);
stream.Position = 0;
var a2 = formatter.Deserialize(stream);
Console.WriteLine((a2 as A).str);
Console.ReadKey();
}
}


发现str字段还是被保存起来了,这说明即使实现了ISerializable,序列化时还是会保存所有字段,那应该仍然使用到了反射(源码比较复杂,应该是哪个地方没有注意到),如果一样使用到了反射,那实现ISerializable接口还有多大意义。

求大神解答一下
...全文
233 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojunjor 2018-03-19
  • 打赏
  • 举报
回复
引用 5 楼 summergo123321 的回复:
这个东西,不用反射,但串行化方式你必须自主完成,如果类很长,比如30个属性,你需要码好长的代码,当然你写个代码自动生成的工具也行,否则很累还容易出错,打的字越多,出错可能越大。。。 你的描述很奇怪, 这个接口目的是自主控制串行化,又不是为了不用反射(虽然真的没有用),即使他用到反射也不至于说他没意义吧,反射是个好东西,。。。
我明白你的意思,我原本的疑问在于自定义序列化时没有自定义保存的字段也被序列化保存了
mk_lucifer 2018-03-16
  • 打赏
  • 举报
回复
这个东西,不用反射,但串行化方式你必须自主完成,如果类很长,比如30个属性,你需要码好长的代码,当然你写个代码自动生成的工具也行,否则很累还容易出错,打的字越多,出错可能越大。。。 你的描述很奇怪, 这个接口目的是自主控制串行化,又不是为了不用反射(虽然真的没有用),即使他用到反射也不至于说他没意义吧,反射是个好东西,。。。
xiaojunjor 2018-03-15
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
引用 2 楼 wddw1986 的回复:
我明白了,感谢
xiaojunjor 2018-03-15
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
引用 2 楼 wddw1986 的回复:
原来是这样。 可是最开始对象里的str字段的值为什么会被保存下来?
cheng2005 2018-03-15
  • 打赏
  • 举报
回复
引用 楼主 xiaojunjor 的回复:
我在看《CLR via C#》里面提到默认的序列化是使用反射实现的,可以通过实现ISerializable接口避免使用反射来序列化 我查了一下源码,发现确实如果实现了ISerializable,就没有调用默认的序列化方法 如果按照这个思想,就是说ISerializable.GetObjectData中SerializationInfo没有AddValue的数据都不会被序列化保存。简单写了个代码测试

    [Serializable()]
    class A : ISerializable
    {
        public string str = "abc";
        public int i = 10;

        public A()
        {

        }

        public A(SerializationInfo info, StreamingContext context)
        {
            this.i = info.GetInt32("i");
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("i", 10);
        }
    }

    class Demo
    {
        public static void Main(String[] args)
        {
            MemoryStream stream = new MemoryStream();
            var formatter = new BinaryFormatter();
            A a = new A();
            formatter.Serialize(stream, a);
            stream.Position = 0;
            var a2 = formatter.Deserialize(stream);
            Console.WriteLine((a2 as A).str); 
            Console.ReadKey();
        }
    }
发现str字段还是被保存起来了,这说明即使实现了ISerializable,序列化时还是会保存所有字段,那应该仍然使用到了反射(源码比较复杂,应该是哪个地方没有注意到),如果一样使用到了反射,那实现ISerializable接口还有多大意义。 求大神解答一下
测试代码都写错了,当然没法得出正确的结论。
            MemoryStream stream = new MemoryStream();
            var formatter = new BinaryFormatter();
            A a = new A();
            a.str = "790";//修改一下str
            formatter.Serialize(stream, a);
            stream.Position = 0;
            var a2 = formatter.Deserialize(stream);
            Console.WriteLine((a2 as A).str);
            Console.ReadKey();
xuzuning 2018-03-15
  • 打赏
  • 举报
回复
str字段还是被保存起来了 吗? 你给 a.str 另外赋个值看看

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧