2017-08-13 122 views
0

我不明白在类上实现ISerializable时使用[NonSerialized]属性。我参加了“C#编程”(微软20-483)课程,仅在少数例子中使用过,但没有详细说明。
借此类:C#:[NonSerialized]实施ISerializable时

[Serializable] 
public class TestNonSerializable : ISerializable 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    [NonSerialized] 
    private int _Age; 
    public int Age 
    { 
     get { return this._Age; } 
     set { this._Age = value; } 
    } 

    public TestNonSerializable() 
    { } 

    public TestNonSerializable(SerializationInfo info, StreamingContext context) 
    { 
     FirstName = info.GetValue("Name", typeof(string)) as string; 
     LastName = info.GetValue("LastName", typeof(string)) as string; 
     // I expect this to throw an exception because the value doesn't exists. 
     // But it exists! 
     Age = (int)info.GetValue("Age", typeof(int)); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("Name", FirstName); 
     info.AddValue("LastName", LastName); 
     // I expect this to be empty 
     info.AddValue("Age", Age); 
    } 
} 

我评论我的期望:_Age的是,我不想序列化的私人领域。我专门编写了GetObjectData来序列化它。这是一件好奇的事情,但我想了解如何处理[NonSerialized]
如果我运行在Main是这样的:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var myObject = new TestNonSerializable() 
     { 
      FirstName = "Foo", 
      LastName = "Bar", 
      Age = 32, 
     }; 

     // Instanciate a SOAP formatter 
     IFormatter soapFormat = new SoapFormatter(); 

     // Serialize to a file 
     using (FileStream buffer = File.Create(@"D:\temp\TestNonSerializable.txt")) 
     { 
      // In the file generated, I expect the age to be empty. But the value 
      // is set to 32 
      soapFormat.Serialize(buffer, myObject); 
     } 

     // Deserialize from a file 
     using (FileStream buffer = File.OpenRead(@"D:\temp\TestNonSerializable.txt")) 
     { 
      // The age is being deserialized 
      var hydratedObject = soapFormat.Deserialize(buffer); 
     } 
    } 
} 

年龄是有...在序列化对象是文件和再水化对象。我的问题是:为什么?这种情况下[NonSerialized] 属性有什么用处,因为我们只需要在GetObjectData方法中不添加Age? 我很明显错过了一些东西,但我无法弄清楚什么。 谢谢!

编辑:例子是存在于课程:

[Serializable] 
public class ServiceConfiguration : ISerializable 
{ 
    [NonSerialized] 
    private Guid _internalId; 
    public string ConfigName { get; set; } 
    public string DatabaseHostName { get; set; } 
    public string ApplicationDataPath { get; set; } 
    public ServiceConfiguration() 
    { 
    } 
    public ServiceConfiguration(SerializationInfo info, StreamingContext ctxt) 
    { 
     this.ConfigName 
      = info.GetValue("ConfigName", typeof(string)).ToString(); 
     this.DatabaseHostName 
      = info.GetValue("DatabaseHostName", typeof(string)).ToString(); 
     this.ApplicationDataPath 
      = info.GetValue("ApplicationDataPath", typeof(string)).ToString(); 
    } 
    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("ConfigName", this.ConfigName); 
     info.AddValue("DatabaseHostName", this.DatabaseHostName); 
     info.AddValue("ApplicationDataPath", this.ApplicationDataPath); 
    } 
} 
+0

是因为你将这个属性应用到私有字段,而序列化器实际上是序列化属性?它并不妨碍通过在支持域上应用[NonSerialized]来序列化财产。也请检查[这个答案](https://stackoverflow.com/questions/4184680/set-the-nonserializedattribute-to-an-auto-property) – kennyzx

+0

谢谢,但链接并没有真正帮助我:(我发现回答微软网站,我认为... – benichka

回答

1

好了,我发现微软网站一些有趣的事情:
https://docs.microsoft.com/en-us/dotnet/api/system.nonserializedattribute?view=netframework-4.7

为目标对象NonSerializedAttribute属性是可序列化类的公有和私有字段。默认情况下,除非使用SerializableAttribute标记,否则类不可序列化。在序列化过程中,默认情况下,类的所有公共和专用字段都将被序列化。在序列化过程中排除标有NonSerializedAttribute的字段。如果您使用XmlSerializer类来序列化对象,请使用XmlIgnoreAttribute类来获得相同的功能。 或者,实现ISerializable接口以显式控制序列化过程。请注意,实现ISerializable的类仍必须标记为SerializableAttribute。

所以,基本上,这就是为什么我实现ISerializable当不明白使用[NonSerialized]:他们不打算一起工作。