【问题标题】:C#: [NonSerialized] when implementing ISerializableC#:实现 ISerializable 时的 [NonSerialized]
【发布时间】:2018-01-21 12:01:14
【问题描述】:

在类上实现ISerializable 时,我不明白[NonSerialized] 属性的使用。我参加了“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]有什么用 属性在这种情况下,因为我们只需要不添加 AgeGetObjectData 方法? 我显然错过了一些东西,但我不知道是什么。 谢谢!

编辑:课程中的示例:

[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);
    }
}

【问题讨论】:

  • 是不是因为您将此属性应用于私有字段,而序列化程序实际上是对属性进行序列化?它不会通过在支持字段上应用 [NonSerialized] 来阻止属性被序列化。也请查看this answer
  • 谢谢,但链接并没有真正帮助我 :( 我在 Microsoft 网站上找到了答案,我想...

标签: c# serialization iserializable


【解决方案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] 的用法:它们不适合一起工作。

【讨论】:

    猜你喜欢
    • 2012-09-17
    • 2013-10-21
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多