2010-07-16 28 views
7

Câu hỏi: Tôi sử dụng một lớp từ điển có thể tuần tự hóa, được tìm thấy tại http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx , để sắp xếp theo thứ tự từ điển. Hoạt động tốt, nhưng tôi gặp phải vấn đề khó chịu.Từ điển có thể tuần tự hóa, cách đặt tên khóa?

 <System.Xml.Serialization.XmlRoot("DataBase")> _ 
    Public Class cDataBase 
     <System.Xml.Serialization.XmlNamespaceDeclarations()> _ 
     Public ns As New System.Xml.Serialization.XmlSerializerNamespaces() 


     <System.Xml.Serialization.XmlElement("Tables")> _ 
     Public Tables1 As New SerializableDictionary(Of String, cTable) 


    End Class ' cDataBase 

Khi tôi serialize thể hiện của lớp trên, vì điều này, xml tạo trông như thế này:

<Tables> 
<item> 
    <key> 
    <string>MyTable</string> 
    </key> 
    <value> 
    <Table CreationDate="0001-01-01T00:00:00" LastModified="0001-01-01T00:00:00"> 
     <Columns> 
     <Column Name="PrimaryKeyName"> 
      <DataType>Uniqueidentifier</DataType> 
      <Length>36</Length> 
     </Column> 
     </Columns> 
     <Rows> 
     <Row> 
      <Item>Reihe1</Item> 
      <Item>Reihe2</Item> 
      <Item>Reihe3</Item> 
     </Row> 
     <Row> 
      <Item>Reihe1</Item> 
      <Item>Reihe2</Item> 
      <Item>Reihe3</Item> 
     </Row> 

nào sẽ là tốt nếu duy nhất tôi có thể tìm ra cách để đổi tên chìa khóa từ < chuỗi > một cái gì đó được xác định trong một thuộc tính

<key> 
    <string>MyTable</string> 
    </key> 

về cơ bản giống như XmlArrayItem thuộc tính, chẳng hạn như dưới đây, nếu (chỉ) vào từ điển là một mảng ...

 <System.Xml.Serialization.XmlArray("Tables")> _ 
     <System.Xml.Serialization.XmlArrayItem("Table")> _ 
     Public Tables As New List(Of cTable) 

tôi muốn cố gắng thay đổi Trong String để một lớp tùy chỉnh được thừa kế từ chuỗi, mà tôi có thể trang bị với một cái tên, nhưng vấn đề là, người ta không thể kế thừa từ chuỗi ...

Trả lời

0

Bạn có thể chuyên mẫu Từ điển hoặc lấy được từ chuyên môn để sắp xếp theo thứ tự bạn muốn.

1

Nếu tôi đọc câu hỏi của bạn một cách chính xác, bạn muốn thay đổi sản lượng theo bộ của bạn từ này:

<Tables> 
    <item> 
    <key> 
     <string>MyTable</string> 
    </key> 
    <value> 
     <!-- snip --> 
    </value> 
    </item> 
</Tables> 

Để một cái gì đó như thế này:

<Tables> 
    <item> 
    <key> 
     <TableId>MyTable</TableId> 
    </key> 
    <value> 
     <!-- snip --> 
    </value> 
    </item> 
</Tables> 

Bạn cũng nói rằng một trong những cách bạn có thể đạt được điều này sẽ là tạo loại của riêng bạn được thừa kế từ System.String, mà - như bạn cũng đề cập - rõ ràng là không thể bởi vì nó là sealed.

Bạn thể tuy nhiên đạt được kết quả tương tự bằng cách đóng gói các giá trị quan trọng trong kiểu riêng của bạn, và sau đó kiểm soát XmlSerializer đầu ra sử dụng một XmlTextAttribute (xem MSDN):

Theo mặc định, XmlSerializer serializes một thành viên của lớp như một phần tử XML . Tuy nhiên, nếu bạn áp dụng XmlTextAttribute cho một thành viên, thì XmlSerializer sẽ dịch giá trị thành văn bản XML. Điều này có nghĩa là giá trị được mã hóa thành nội dung của một phần tử XML.

Trong trường hợp của bạn, bạn muốn sử dụng các thuộc tính như sau:

public class TableId 
{ 
    [XmlText] 
    public string Name 
    { 
     get; 
     set; 
    } 
} 

Và sau đó sử dụng loại này như là chìa khóa (s) để Dictionary của bạn. Mà nên đạt được những gì bạn muốn.

0

Mặc dù nó có thể hơi mất chủ đề, tôi cần phải hỏi tại sao lại sử dụng XML để tuần tự hóa nó? Nếu bạn chỉ muốn lưu trạng thái đối tượng cho tương lai, tôi sẽ đề xuất JSON thay vì XML.

Một lợi ích lớn là bạn có thể dễ dàng lưu một lớp Từ điển thông thường mà không phải viết bất kỳ mã đặc biệt nào. Tải trọng cũng nhỏ hơn nhiều so với JSON vì vậy đây là định dạng tuyệt vời để gửi qua dây nếu cần.

Scott Gu có một chút thông tin về việc sử dụng JavascriptSerializer here. Tôi sẽ đề nghị làm cho nó một phương pháp mở rộng trên đối tượng. Sau đó, bạn có thể làm điều này:

Dictionary<int, string> myDict = new Dictionary<int,string>(); 
myDict.Add(10,"something"); 
string jsonData = myDict.ToJSON(); 

Nếu đây là điều bạn quan tâm để cho tôi biết và tôi có thể đăng mã cho các phương pháp tiện ích mở rộng mà tôi sử dụng. (sry không làm việc và tôi không có họ với tôi ở đây.)

+0

Thứ nhất, tôi là giới hạn .NET 2.0, và thứ hai, vấn đề chính là từ điển là một kiểu generic và không serializable (không phải trong JSON hoặc là). Tôi đang tuần tự hóa thành XML vì XML được sử dụng rộng rãi hơn và tốt hơn để đọc, nếu được tuần tự hóa từ .NET 2.0. –

0

Vì bạn có nguồn, bạn có thể sửa đổi nó để nó tra cứu các thuộc tính XML nếu chúng có mặt. Không có gì là thiêng liêng về gia đình người quen thuộc XML - giống như bất kỳ người gác mộ nào khác có thể được tra cứu thông qua sự phản chiếu. Một khi yo u có mà bạn có thể đặt tên mới vào mã nơi trong người sáng tạo và/hoặc đọc thẻ XML. Bạn cũng có thể thêm 2 thông số để ghi đè tên thẻ một cách rõ ràng, như ReadXml (myReader, "Tables", "Table") và thay đổi mã để thực hiện theo các tên này thay vì mặc định. Phải chuyển sang C# mặc dù :-)

0

Cân nhắc thay thế từ điển bằng KeyedCollection. Nó được tuần tự hóa thành một danh sách, kết quả là nó nhỏ hơn và tên nút XML là tên của các thuộc tính/trường cTable.

[Serializable] 
[CollectionDataContract] 
public class TablesCollection : KeyedCollection<string, cTable> 
{ 
    protected override string GetKeyForItem(cTable item) 
    { 
     return item == null ? String.Empty : item.TableName; 
    } 
} 
0

không thể nói rằng tôi đã sử dụng mà thực hiện từ điển serializeable, nhưng trong trường hợp bạn sẵn sàng thử những điều mới, có một chút lớp trừu tượng được biết đến gọi KeyedCollection đó là hoàn toàn serializeable, hỗ trợ chủ chốt dựa trên quyền truy cập và có thể dễ dàng được triển khai dưới dạng từ điển.

.Net 2.0 Keyed Collection

Các vấn đề liên quan