2010-08-27 248 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 

不是最好的解決方案,但它確實提供了基本的機制防止意外的變化。

相關問題