C#: [NonSerialized] при реализации ISerializable
Я не понимаю использование [NonSerialized]
атрибут при реализации ISerializable
на уроке. Я посещал курс "Программирование на C#" (Microsoft 20-483), и он используется в нескольких примерах, но не в деталях.
Возьмите этот класс:
[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]
атрибут в этом случае, так как мы просто не должны добавлять Age
в GetObjectData
метод? Я явно что-то упускаю, но не могу понять, что. Спасибо!
Изменить: пример, который присутствует в курсе:
[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);
}
}
1 ответ
Итак, я нашел что-то интересное на сайте Microsoft:
https://docs.microsoft.com/en-us/dotnet/api/system.nonserializedattribute?view=netframework-4.7
Целевые объекты для атрибута NonSerializedAttribute являются открытыми и закрытыми полями сериализуемого класса. По умолчанию классы не сериализуются, если они не помечены как SerializableAttribute. В процессе сериализации все открытые и закрытые поля класса сериализуются по умолчанию. Поля, помеченные как NonSerializedAttribute, исключаются при сериализации. Если вы используете класс XmlSerializer для сериализации объекта, используйте класс XmlIgnoreAttribute для получения той же функциональности. В качестве альтернативы, реализуйте интерфейс ISerializable для явного управления процессом сериализации. Обратите внимание, что классы, реализующие ISerializable, должны быть помечены как SerializableAttribute.
Так что, в основном, поэтому я не понял, как использовать [NonSerialized]
при реализации ISerializable
: они не предназначены для совместной работы.