【问题标题】:Overridden Deserialize in XmlSerializer is never called永远不会调用 XmlSerializer 中的重写反序列化
【发布时间】:2011-07-09 21:12:55
【问题描述】:

我慢慢感觉自己的理智在边缘磨损,而我的思绪也在慢慢流失。

我想扩展由于某种原因不支持反序列化通知的 XmlSerializer。

我有以下代码:

public class NotificationXmlSerializer : XmlSerializer
{
    public NotificationXmlSerializer(Type type)
        : base(type)
    { 
    }

    protected override object Deserialize(XmlSerializationReader reader)
    {
        var x = base.Deserialize(reader);
        var methods = x.GetType().GetMethods().Where(method => method.GetCustomAttributes(true).Any(attr => attr is OnDeserializedAttribute));

        return x;
    }
}

并以这种方式使用它:

    using (MemoryStream fs = new MemoryStream())
    {
        var x = new NotificationXmlSerializer(typeof(int));
        x.Serialize(fs, 5);
        fs.Seek(0, SeekOrigin.Begin);
        var y = x.Deserialize(fs);
    }

但是,如果我在我的反序列化覆盖中放置一个断点,它就永远不会被命中!即使我故意在里面抛出异常,程序功能也是正常的,所以我确信它永远不会被命中。

他们为什么要让我重写一个内部方法 Deserialize 而不让我通过它来影响任何东西?

我做错了什么?

最好的问候,马克斯

【问题讨论】:

    标签: c# extend xmlserializer


    【解决方案1】:

    首先,正如 MSDN 所说,该方法是供内部使用的:

    此 API 支持 .NET Framework 基础结构,并不打算直接从您的代码中使用。

    其次,如果你用 Reflector 查看XmlSerializer,你会发现唯一调用这个方法的地方。简化的控制流程为:

    public object Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
    {
        …
        try
        {
            if (this.primitiveType != null)
            {
                …
                return this.DeserializePrimitive(xmlReader, events);
            }
            if ((this.tempAssembly == null) || this.typedSerializer)
            {
                XmlSerializationReader reader = …
                try
                {
                    return this.Deserialize(reader);
    …
    

    即使此方法 (Deserialize(XmlReader, string, XmlDeserializationEvents)) 是从所有其他 Deserialize 方法调用的,但这并不意味着控制流必须以 Deserialize(XmlSerializationReader) 结束。

    我的建议:获取XmlSerializer 的参考源,研究行为,然后以另一种方式解决您的问题,或者以调用覆盖的方式调整外部条件。就我个人而言,我会避免依赖覆盖该方法。您最终会得到更稳定的行为防止兼容性问题与框架的未来版本。

    【讨论】:

    • +1 这就是我使用反射器的程度 - 内部流程非常复杂,我也不建议 OP 在这种情况下依赖覆盖
    • 谢谢。我知道我应该更仔细地阅读 MSDN,但在这种情况下,它看起来很像扩展功能的传统方式 - 内部方法执行大量管道,然后使用简化的参数调用 Deserialize。我被我的假设愚弄了,它必须是它在逻辑上看起来的样子。
    • @Max 如果你想要可扩展性——忘记 XmlSerializer。并使用... ...您自己的序列化程序。据我所知,没有其他可行的选择。
    • 好吧.. 抱怨。似乎关于 XmlSerializer 实现了很多事情可能会更好 - 例如,如果序列化程序不是直接拒绝接口,而是在序列化时将具体类型保存为属性,这可能会很方便 - 当它们有时应该相当简单已经完成了所有其他工作。无论如何,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多