2017-08-13 2 views
0

Ich verstehe nicht die Verwendung des Attributs [NonSerialized] bei der Implementierung ISerializable auf einer Klasse. Ich besuchte den Kurs "Programmierung in C#" (Microsoft 20-483) und es wird in einigen Beispielen verwendet, aber nicht in Details.
Nehmen Sie diese Klasse:C#: [NonSerialized] bei der Implementierung von 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); 
    } 
} 

bemerkte ich, was ich erwarte: _Age ist ein privates Feld, das will ich nicht serialisiert werden. Ich habe es speziell geschrieben in , um es zu serialisieren. Es ist eine seltsame Sache zu tun, aber ich wollte verstehen, wie [NonSerialized] würde behandelt werden.
Wenn ich laufe so etwas wie dies in den 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); 
     } 
    } 
} 

Das Alter ist es ... In der Datei, in der das serialisierte Objekt ist und in dem rehydratisierten Objekt. Meine Frage ist: Warum? Was nützt das Attribut [NonSerialized] in diesem Fall, da wir Age in der GetObjectData Methode einfach nicht hinzufügen müssen? Ich vermisse eindeutig etwas, aber ich kann nicht herausfinden, was. Danke!

bearbeiten: das Beispiel, das im Verlauf vorhanden ist:

[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

Liegt das daran, dass Sie dieses Attribut auf ein privates Feld anwenden, während der Serializer die Eigenschaft serialisiert? Es verhindert nicht, dass die Eigenschaft serialisiert wird, indem [NonSerialized] auf dem Sicherungsfeld angewendet wird. Überprüfen Sie bitte auch [diese Antwort] (https://StackOverflow.com/questions/4184680/set-the-Nonserializedattribute-to-an-auto-property) – kennyzx

+0

Danke, aber der Link hat mir nicht wirklich geholfen :(Ich fand ein Antwort auf Microsoft WebSite, denke ich ... – benichka

Antwort

1

OK, so fand ich etwas Interessantes auf Microsoft-Website:
https://docs.microsoft.com/en-us/dotnet/api/system.nonserializedattribute?view=netframework-4.7

Die Zielobjekte für die Das NonSerializedAttribute-Attribut sind öffentliche und private Felder einer serialisierbaren Klasse. Standardmäßig sind Klassen nicht serialisierbar, es sei denn, sie sind mit SerializableAttribute gekennzeichnet. Während des Serialisierungsprozesses werden alle öffentlichen und privaten Felder einer Klasse standardmäßig serialisiert. Felder, die mit NonSerializedAttribute markiert sind, werden während der Serialisierung ausgeschlossen. Wenn Sie die XmlSerializer-Klasse zum Serialisieren eines Objekts verwenden, verwenden Sie die XmlIgnoreAttribute-Klasse, um die gleiche Funktionalität zu erhalten. Implementieren Sie alternativ die ISerializable-Schnittstelle, um den Serialisierungsprozess explizit zu steuern. Beachten Sie, dass Klassen, die ISerializable implementieren, weiterhin mit SerializableAttribute gekennzeichnet sein müssen.

Also, im Grunde, das ist, warum ich nicht die Verwendung von [NonSerialized] verstanden habe, wenn ISerializable Umsetzung: sie sind nicht zusammen zu arbeiten bedeutet.

Verwandte Themen