2017-08-13 54 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]:他們不打算一起工作。