2010-08-27 254 views
9

我有一个返回XElement的API,我希望这些XElement背后的文档是不可变的(只读)。我需要它:有没有办法创建一个不可变(只读)的XDocument?

  • 不给开发者去改变它小心:)
  • 提高性能的能力 - 创建XDocument的副本可能是在某些情况下的性能“沉重”的操作。

这似乎并不可能继承&覆盖在XDocument/XElement/XContainer必要的行为,因为所有的虚拟方法有标记为internal

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

所以我的问题是 - 有办法让它发生,或者最好有一个不同的API来返回像XPathNavigator的东西,或者最好有自己的类如IReadOnlyXElement等。

回答

4

您可以创建一个类似于ReadOnlyCollection<T>XElement包装。

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交互。然后您可以限制开发人员在代码中写入文件的能力。

我说限制,因为有足够的信息(位置,架构(如果需要))开发人员可以使用股票XMLClasses做任何他们想要的。最终的结果都是让文件只读在磁盘上,并确保它们(开发人员,用户)没有权限更改文件的只读访问权限。

12

我怀疑这个autor仍在等待答案,但也许别人会觉得它有用。

可以种-的使一成不变的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 

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

相关问题