代码之家  ›  专栏  ›  技术社区  ›  Stefan Steiger Marco van de Voort

可序列化字典,如何设置键名?

  •  7
  • Stefan Steiger Marco van de Voort  · 技术社区  · 15 年前

    问:我使用的是一个可序列化字典类,位于 http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx

          <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
    

    当我序列化上述类的实例时,

    <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>
    

    如果我能知道如何从 <string>属性中定义的内容

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

    基本上类似于XmlArrayItem属性,如下面所示,如果(仅)字典是一个数组。。。

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

    我想尝试将String的类型更改为从String继承的自定义类,我可以为其配备一个名称,但问题是,不能从String继承。。。

    6 回复  |  直到 15 年前
        1
  •  1
  •   Dougc    15 年前

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

    对这样的事情:

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

    System.String ,正如你提到的,这显然是不可能的,因为 sealed

    你呢 可以 但是,通过将键值封装在自己的类型中,然后控制 XmlSerializer 使用 XmlTextAttribute (见 MSDN ):

    将类成员序列化为XML 元素。但是,如果您应用 XmlTextAttribute,则 XmlSerializer转换其值 转换为XML文本。这意味着 XML元素。

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

    然后将此类型用作 Dictionary . 这应该能达到你想要的。

        2
  •  0
  •   onof    15 年前

        3
  •  0
  •   Kelly    15 年前

    虽然这可能有点离题,但我需要问一下,为什么要使用XML来序列化它?如果您只是想为将来保存对象状态,我建议使用JSON而不是XML。

    一个很大的好处是您可以轻松地保存一个普通的Dictionary类,而不必编写任何特殊的代码。有效负载也比JSON小得多,所以如果需要的话,它是一种很好的跨线发送格式。

    scottgu有一些关于使用JavascriptSerializer的信息 here

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

    如果这是你感兴趣的东西让我知道,我可以张贴我使用的扩展方法的代码。(我不在工作,也没有带着它们。)

        4
  •  0
  •   ZXX    15 年前

    既然有了源代码,就可以对其进行修改,以便它在XML属性存在时查找它们。XML属性库家族并没有什么神圣的标志——它们就像任何其他可以通过反射来查找的属性库一样。一旦你有了,你就可以把新的名字放到代码中,在creater和/或读取XML标记。也可以只添加2个参数来显式重写标记名,比如ReadXml(myReader,“Tables”,“Table”),并将代码改为跟随这些名称而不是默认值。我得换成C#尽管:-)

        5
  •  0
  •   Boris Modylevsky    15 年前

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