有没有办法创建不可变(只读)XDocument?

问题描述 投票:0回答:3

我有一个返回

XElement
的 API,我希望这些
XElement
背后的文档是不可变的(只读)。我需要它的目的是:

  • 不要让开发人员能够意外更改它:)
  • 提高性能 - 创建
    XDocument
    的副本在某些情况下可能是性能“繁重”操作。

似乎不可能继承和重写

XDocument
/
XElement
/
XContainer
中必要的行为,因为那里的所有虚拟方法都被标记为
internal
:

internal virtual void XContainer.AddAttribute(XAttribute a)
{
}

所以我的问题是 - 有没有办法让它发生,或者最好有一个不同的 API,它要么返回类似

XPathNavigator
的东西,要么最好有自己的类,比如
IReadOnlyXElement
等。 ?

c# .net linq-to-xml
3个回答
13
投票

我怀疑作者仍在等待答案,但也许其他人会发现它有用。

您可以通过使用其更改事件使 XDocument 不可变:

    class Program
    {
        static void Main(string[] args)
        {
            var xdoc = XDocument.Parse("<foo id=\"bar\"></foo>");
            xdoc.Changing += (s, ev) =>
            {
                throw new NotSupportedException("This XDocument is read-only");
            };

            try
            {
                xdoc.Root.Attribute("id").Value = "boo";
            }
            catch (Exception e)
            {
                Console.WriteLine("EXCEPTION: " + e.Message);
            }

            Console.WriteLine("ID on exit: " + xdoc.Root.Attribute("id").Value);

            Console.ReadKey();
        }
    }

// Console output:
// EXCEPTION: This XDocument is read-only
// ID on exit: bar

不是最好的解决方案,但它确实提供了防止意外更改的基本机制。


5
投票

您可以创建一个类似于

XElement
ReadOnlyCollection<T>
包装器。

public sealed class ReadOnlyXElement
{
    private readonly XElement _element;


    public string Value
    {
        get { return _element.Value; }
    }


    public ReadOnlyXElement(XElement element)
    {
        _element = element;
    }


    public IEnumerable<ReadOnlyXElement> Elements()
    {
        foreach (var child in _element.Elements())
        {
            yield return new ReadOnlyXElement(child);
        }
    }

    public IEnumerable<ReadOnlyXElement> Elements(XName xname)
    {
        foreach (var child in _element.Elements(xname))
        {
            yield return new ReadOnlyXElement(child);
        }
    }
}

3
投票

恕我直言,最好创建自己的包装类来与 XDocuments/XElements 交互。 然后,您可以限制开发人员在代码中重写文件的能力。

我说限制是因为有了足够的信息(位置、模式(如果需要)),开发人员可以使用现有的 XMLClass 来完成他们想做的任何事情。最终的结果就是使文件在磁盘上只读,并确保他们(开发人员、用户)无权更改文件的只读访问权限。

© www.soinside.com 2019 - 2024. All rights reserved.