如题,在网上找了份具体的描述:
————————————————————————————————————————
http://www.cnblogs.com/xiashengwang/archive/2012/07/18/2598108.html
四,控制序列化和反序列化
将SerializationAttribute这个attribute应用于一个类型时,所有的实例字段(public,private,protected等)都会被序列化(在标记了[Serialization]特性的类型中,不要使用C#的“自动实现属性”来定义属性。这是因为字段名是由编译器自动生成的,而每次重新编译,生成的名称都不同)
————————————————————————————————————————
但是我自己实现了下,是可以的。
代码:
[Serializable] public class SerializeClass { public int ID { get; set; } public string Name { get; set; } public override string ToString() { return string.Format("ID:{0},Name:{1}", ID, Name); } } public static void Test7() { SerializeClass s = new SerializeClass() { ID = 1, Name = "test1" }; BinaryFormatter format = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); format.Serialize(stream, s); stream.Position = 0; var obj = format.Deserialize(stream) as SerializeClass; if (obj != null) { Console.WriteLine(obj.ToString()); } } 输出:ID:1,Name:test1
请问,书上说的对吗?如果对,是我理解的有问题吗?
这位同学看书很认真,居然连页脚的文字都看了,表扬一下。
如果按照“每次重新编译,生成的名称都不同”这个逻辑的话,
你的测试是无效的,因为你这是同一个编译。
你试着将序列化持久化到文件,然后在另外一个编译中反序列化看看。
谢谢各位的回复,我生成了一个文件:
SerializeClass s = new SerializeClass()
{
ID = 1,
Name = "test1"
};
BinaryFormatter format = new BinaryFormatter();
FileStream fs = new FileStream("T1.txt", FileMode.Create);
format.Serialize(fs, s);
然后再次运行控制台程序(删掉dll,重新编译后),反序列化:
BinaryFormatter format = new BinaryFormatter();
FileStream fs = new FileStream("T1.txt", FileMode.Open);
var obj = format.Deserialize(fs) as SerializeClass;
if (obj != null)
{
Console.WriteLine(obj.ToString());
}
结果显示:
ID:1,Name:test1
因为我用的是.net 4.0,然后我用试了3.5、2.0等都是一样的,然后我怀疑是机器的原因,找同事帮忙生成了一个txt,结果和我本机生成的txt比对是完全一样的。
但因为我们都是用vs2013的,所以可能C#编译器是一样的。
所以书上说的“每次重新编译,生成的名称都不同”应该不对,或者至少不严谨,可能有些机器C#编译器版本不同,会导致生成的字段不同。
不过看到生成的txt文件(部分):<Name>k__BackingField ,把命名空间等也加进去了,所以最好还是用Newtonsoft.Json 第三方dll,这个生成的是是类似于:
{"ID":123,"Name":"test232"}
是没有命名空间的,所以推荐用它(不是打广告)。
@风筝blog: 这里说的是每次自动生成的私有字段名字是不固定的。不是说属性名称。
你看的版太旧了.
CLR via C# (第四版)是旧的?我才买了不到两个月,不能这样坑人吧。
@爱编程的大叔: 大叔说的对.不过我一直都在用自动属性做序列化.没出过问题..
自动实现属性:
只是会生成具有 k__BackingField 后缀的字段
使用非自动实现属性,就不会有这个后缀
为了避免这个后缀,建议使用 非自动实现属性
而且只对 青色的三个字段进行序列化,红色三角三个属性是不会被序列化的
我觉得你应该理解错了,你把字段名(field)和属性(property)混淆了,编译器自动生成的是字段名,属性名是一样的。原版书的Automatically Implemented Properties小节是这样写的:The name of the backing field for an Automatically Implemented Properties is determined by the compiler. 楼上的图可以看到生成的<ID>k__BackingField是private field。