【问题标题】:How to save a list of classes in combination with other variables in c# wpf如何在 c# wpf 中结合其他变量保存类列表
【发布时间】:2013-03-19 14:55:42
【问题描述】:

您好,我刚开始使用 C# WPF,并阅读了有关序列化以存储或加载数据的信息。我的问题是如何存储一个包含另一个类列表和一些附加参数的类?

我的第一个类(MeterValues)包含许多参数(类型、速度等)

public class MeterValues{}

我现在创建了第二个类来存储包含第一类类型的多个实例的列表。 (所以如果我有 3 个不同的仪表,这个列表大小 = 3)

public class MeterValuesList : IList<MeterValues>{}

现在我想给第二个类添加一个额外的参数,这个参数独立于第一个类,所以它应该只保存一次。 (不是针对 class1 的每个实例)

为了让我的问题清楚,我可以将额外的参数添加到第一个类,但是如果我有 100 个不同的仪表,则参数存储 100 次,我只需要存储一次。

知道如何做到这一点吗?

PS:如果您需要任何其他信息,请尽管询问,我非常渴望学习并帮助您帮助我解决这个问题。提前致谢。

更新:

我可以将 MeterValuesList 类保存到 .xml 文件中,但只有 List 存储在文件中,额外参数不显示(在我将其写入文件之前,它就在类中,检查它带有调试器但未显示在文件中)

MeterValuesList meterValuesList = DataContext as MeterValuesList;
meterValuesList.CommSettings = "Com5:19200,8,n,1";

    FileStream stream = null;
    try
    {
        stream = new FileStream(filename, FileMode.Create, FileAccess.Write);
        XmlSerializer serializer = new XmlSerializer(typeof(MeterValuesList));
        serializer.Serialize(stream, meterValuesList);
        stream.Close();
    }

这是将类保存到 xml 文件后的结果。缺少额外的参数。

<?xml version="1.0"?>
<ArrayOfMeterValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MeterValues></MeterValues>
</ArrayOfMeterValues>

【问题讨论】:

  • 必须承认,PS 很棒。但您可能希望将其改写为更少“为我解决问题”而更多“帮助我学习”。
  • MeterValuesList 需要从 IList 派生有什么特殊原因吗?你不能只创建一个包含 List 属性的新类吗?

标签: c# wpf serialization


【解决方案1】:

除非您计划覆盖或扩展 IList 已有的功能,否则没有理由在您的 MeterValuesList 类中继承它。这感觉就像是使用“has a”关系而不是“is a”关系。

试试这个:

public class MeterValuesGroup
{
    List<MeterValues> MeterList { get; set; }
    int ExtraParameter { get; set; }
    // whatever additional parameters you need here.
}

如果你确实需要从 IList 或 IEnumerable 继承,你可以做类似的事情。但是,为了正确序列化此类,您必须在 MeterValues 和 MeterValuesList 中实现 IXmlSerializable。

(这是一个很好的例子:Proper way to implement IXmlSerializable?

public class MeterValuesList : IList<MeterValues>, IXmlSerializable
{
    MeterValues[] _MeterList { get; set; }
    string CommSettings = "Com5:19200,8,n,1";

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteAttributeString("CommSettings ", CommSettings );

        foreach (var mv in _MeterList)
        {
            // kind of a bad example, but hopefully you get the idea
            if (mv== null) 
                return;
            writer.WriteStartElement("MeterValues");
            mv.WriteXml(writer);
            writer.WriteEndElement();
        }
    }

【讨论】:

  • 也许他想遍历它,所以他可以像你建议的那样实现它并实现 IEnumerable(例如:codeproject.com/Articles/474678/…
  • @Dzyann 这是一个很好的观点。我希望 OP 回来澄清那部分。
  • 您好,感谢您的回复,我的同事告诉我它必须是 IList,因为他实现了一些使用 IEnumerator 的功能。我认为这就是 Dzyann 的看法。
  • 我为你更新了我的答案。我认为您还需要从 MeterValues 和 MeterValuesList 中的 IXmlSerializable 继承。否则序列化程序将无法识别您的附加字段。
【解决方案2】:

您可以将此属性添加到第二个类 MeterValueList 中并序列化该类,当您对其进行反序列化时,将分配该附加属性。

    MeterValueList m = new MeterValueList();
     m.AdditionalParameter = 100;
    MemoryStream memorystream = new MemoryStream(); 
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(memorystream, m);
    byte[] yourBytesToDb = memorystream.ToArray();
    //here you write yourBytesToDb to database


    //----------read from database---------------------
    //here you read from database binary data into yourBytesFromDb
    MemoryStream memorystreamd = new MemoryStream(yourBytesFromDb);
    BinaryFormatter bfd = new BinaryFormatter();
    MeterValueList  md = bfd.Deserialize(memorystreamd) as MeterValueList ;
    var i  =  md.AdditinalParameter; // must print 100

【讨论】:

  • 您好,感谢您的回复,我的课程必须保存到我在调用对话框后选择的文件中。我是 WPF c# 的新手,我不确定如何调整您的代码,以便将其保存到文件中。所以我不确定如何测试这段代码。
猜你喜欢
  • 2021-02-19
  • 2015-08-06
  • 2012-02-02
  • 2022-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
相关资源
最近更新 更多