为啥 xmlignore 不能与 System.Timers.Timer 类一起使用

Posted

技术标签:

【中文标题】为啥 xmlignore 不能与 System.Timers.Timer 类一起使用【英文标题】:Why is xmlignore not working with System.Timers.Timer class为什么 xmlignore 不能与 System.Timers.Timer 类一起使用 【发布时间】:2017-03-16 08:49:58 【问题描述】:

我正在尝试序列化一个类对象,但在添加 System.Timers.Timer 对象时遇到了问题。

在序列化过程中,我收到以下异常:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll

Additional information: Type 'System.Timers.Timer' in Assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

项目是 .net 4.6 Windows Forms 应用程序

这是我要序列化的类:

using System;
using System.Xml.Serialization;

[Serializable]
[XmlInclude(typeof(CTestClass))]
public class CTestClass

    public CTestClass()
    
        x = 1;
        timer = new System.Timers.Timer();
    

    [XmlElement]
    public int x  get; set; 

    // It seems [XmlIgnore] is being ignored... :-(
    [XmlIgnore]
    public System.Timers.Timer timer  get; set; 

这是我用来序列化类对象的代码:

(注意:需要使用 BinaryFormatter)

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;

    private void TestIt()
    
        CTestClass ctc = new CTestClass();
        SerializeData(ctc);
    

    protected virtual byte[] SerializeData(CTestClass data)
    
        using (var memoryStream = new MemoryStream())
        
            new BinaryFormatter().Serialize(memoryStream, data);
            return memoryStream.ToArray();
        
    

来自评论:

将属性设置为私有 - 没有帮助

    private System.Timers.Timer timer  get; set; 

使用 [NonSerialized] - 没有帮助:

Error   CS0592  Attribute 'NonSerialized' is not valid on this declaration type. It is only valid on 'field' declarations.  TimerSerializationError c:\TimerSerializationError\TimerSerializationError\CTestClass.cs    19  Active

“特别是不使用自动属性——(即没有设置)”——没有帮助:

 Additional information: Type 'System.Timers.Timer' in Assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

【问题讨论】:

您没有使用 XML 序列化,这就是 [XmlIgnore] 属性被忽略的原因。只需让你的计时器private - 无论如何你都不太可能想要公开它。 将计时器更改为私有 -- SAME 错误 很抱歉。也许您可以改用 XmlSerializer,或者从您的类中删除计时器,或者让您的类持有一个“设置”类的实例,其中包含真正的可序列化数据,而只是序列化/反序列化设置类。最后,您还可以选择实现ISerializable,在这种情况下您可以控制序列化中包含的内容。 【参考方案1】:

[Serializable] 属性吸引了您。

因为您使用的是[Serializable] 属性,所以您需要为您的计时器属性添加[NonSerialized],详见this answer。

【讨论】:

严重性代码说明项目文件行抑制状态错误 CS0592 属性“NonSerialized”在此声明类型上无效。它仅对“字段”声明有效。 TimerSerializationError c:\TimerSerializationError\TimerSerializationError\CTestClass.cs 19 活动 我根本不希望它被序列化...... 对,但请特别尝试不使用自动属性——(即不设置)。做支持字段(private System.Timers.Timer timer;),把[NonSerialized]放在上面,然后用getter和setter编写一个公共属性,如果你仍然需要它指向你的支持字段。 NonSerialized 不允许作为属性装饰器 对,[NonSerialized] 在场上,[XmlIgnore] 在属性上。【参考方案2】:

这是我必须做的~完全~忽略计时器对象:

[Serializable]
public class CTestClass : ISerializable

    public CTestClass()
    
        x = 1;
        timer = null;
    

    public int x  get; set; 

    private System.Timers.Timer timer  get; set; 

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    
        info.AddValue("x", x);
    

【讨论】:

以上是关于为啥 xmlignore 不能与 System.Timers.Timer 类一起使用的主要内容,如果未能解决你的问题,请参考以下文章

XmlIgnore的解释和使用

XmlIgnore的使用

在 .NET JSON 序列化期间忽略字段;类似于 [XmlIgnore]?

为啥 NSFileManager 不能与 UIDocumentBrowserViewController 一起使用?

为啥 TransactionScope 不能与 Sqlite 一起使用?

为啥 FileProvider 不能与广播一起使用?