需要覆盖 XMLWriter 的方法

pau*_*011 4 c# overriding

如果值为空,我需要覆盖 XMLWriter 的方法“WriteElementString”以不写入元素,下面的代码不起作用,尝试了overridenew关键字,但它仍然转到框架方法。

public static void WriteElementString(this XmlWriter writer,
                                      string localName,
                                      string value)
{
    if (!string.IsNullOrWhiteSpace(value))
    {
        writer.WriteStartElement(localName);
        writer.WriteString(value);
        writer.WriteEndElement();
    }
}
Run Code Online (Sandbox Code Playgroud)

答案很接近,但正确的解决方案是:

public abstract class MyWriter : XmlWriter
{
    private readonly XmlWriter writer;
    public Boolean skipEmptyValues;

    public MyWriter(XmlWriter writer)
    {
        if (writer == null) throw new ArgumentNullException("Writer");
        this.writer = writer;
    }

    public new void WriteElementString(string localName, string value)
    {
        if (string.IsNullOrWhiteSpace(value) && skipEmptyValues)
        {
            return;
        }
        else
        {
            writer.WriteElementString(localName, value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

JG *_* SD 5

您需要创建一个装饰对象XmlWriter以实现您想要做的事情。 更多关于装饰者模式

public class MyXmlWriter : XmlWriter
{
    private readonly XmlWriter writer;

    public MyXmlWriter(XmlWriter writer)
    {
        if (writer == null) throw new ArgumentNullException("writer");
        this.writer = writer;
    }

    // This will not be a polymorphic call
    public new void WriteElementString(string localName, string value)
    {
        if (string.IsNullOrWhiteSpace(value)) return;

        this.writer.WriteElementString(localName, value);
    }

    // the rest of the XmlWriter methods will need to be implemented using Decorator Pattern
    // i.e.
    public override void Close()
    {
        this.writer.Close();
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

在 LinqPad 中使用上述对象

var xmlBuilder = new StringBuilder();
var xmlSettings = new XmlWriterSettings
{
    Indent = true
};

using (var writer = XmlWriter.Create(xmlBuilder, xmlSettings))
using (var myWriter = new MyXmlWriter(writer))
{
    // must use myWriter here in order for the desired implementation to be called
    // if you pass myWriter to another method must pass it as MyXmlWriter
    //    in order for the desired implementation to be called
    myWriter.WriteStartElement("Root"); 
    myWriter.WriteElementString("Included", "Hey I made it");
    myWriter.WriteElementString("NotIncluded", "");
}

xmlBuilder.ToString().Dump();
Run Code Online (Sandbox Code Playgroud)

输出:

<?xml version="1.0" encoding="utf-16"?>
<Root>
  <Included>Hey I made it</Included>
</Root>
Run Code Online (Sandbox Code Playgroud)

您想要做的是使用扩展方法覆盖一个方法,这不是他们打算做的。请参阅扩展方法 MSDN 页面上的编译时绑定扩展方法部分。编译器将始终解析WriteElementString为由 实现的实例XmlWriter。您需要手动调用您的扩展方法XmlWriterExtensions.WriteElementString(writer, localName, value);,以便您的代码按照您的方式执行。