C# - 在另一个类

时间:2018-02-16 08:50:49

标签: c# xml serialization deserialization

我正在尝试对类进行反序列化,以便在XML文件中保存用户特定的值(如dirpath)。

以下是我班级的片段:

      [Serializable]
       public class CustomSettings
        {
            public string initPath;
            public string InitPath => initPath;
        }

如果我在MainWindow类中执行此操作,序列化和反序列化都可以正常工作:

            CustomSettings cs = new CustomSettings();
            XmlSerializer mySerializer = new XmlSerializer(typeof(CustomSettings));
            StreamWriter myWriter = new StreamWriter(@"U:\Alex\prefs.xml");
            mySerializer.Serialize(myWriter, cs);
            myWriter.Close();

对于反序列化:

        CustomSettings cs = new CustomSettings();
        XmlSerializer _mySerializer = new XmlSerializer(typeof(CustomSettings));
        FileStream myFstream = new FileStream(@"U:\Alex\prefs.xml", FileMode.Open);
        cs = (CustomSettings)_mySerializer.Deserialize(myFstream);
        myFstream.Close();

既然我需要进行几次反序列化,我想我会写两个方法来完成上述工作,但由于可读性,我希望它们在另一个类中。

MainWindow中,我在另一个类中调用此方法,该类再次按预期工作:

 public void WriteSettingsToFile(CustomSettings cs)
    {
        XmlSerializer mySerializer = new XmlSerializer(typeof(CustomSettings));
        StreamWriter myWriter = new StreamWriter(@"U:\Alex\prefs.xml");
        mySerializer.Serialize(myWriter, cs);
        myWriter.Close();
    }

但我写的反序列化功能不起作用。它成功加载文件,返回正确的路径值,但一旦返回调用类,该字符串始终为null。我重写了几次这个方法,尝试void,非void返回一个字符串,静态等等但是我被卡住了。

感谢任何帮助和想法!

修改 这是使用反序列化方法的尝试之一:

 public void GetInitPath(CustomSettings cs)
    {
        XmlSerializer _mySerializer = new XmlSerializer(typeof(CustomSettings));
        FileStream myFstream = new FileStream(@"U:\Alex\prefs.xml", FileMode.Open);
        cs = (CustomSettings)_mySerializer.Deserialize(myFstream);
        myFstream.Close();

    }

编辑2:

在Matthew Watson的帮助下,我能够解决我的问题。

 public void GetInitPath(ref CustomSettings cs)
    {

        XmlSerializer serializer = new XmlSerializer(typeof(CustomSettings));

        using (var myFstream = new FileStream(@"U:\Alex\prefs.xml", FileMode.Open))
        {
            cs = (CustomSettings)serializer.Deserialize(myFstream);
        }
    }

1 个答案:

答案 0 :(得分:1)

这是你的方法不起作用:

public void GetInitPath(CustomSettings cs)
{
    XmlSerializer _mySerializer = new XmlSerializer(typeof(CustomSettings));
    FileStream    myFstream     = new FileStream(@"U:\Alex\prefs.xml", FileMode.Open);
    cs                          = (CustomSettings)_mySerializer.Deserialize(myFstream);
    myFstream.Close();
}

这种方法的问题在于它没有返回结果。

它会覆盖cs的引用,该引用传递给GetInitPath()并引用从.Deserialise()返回的对象,但这不会更改传递给GetInitPath()的原始对象}。

解决方案是将参数声明为ref参数,或者(更好)更改方法以返回结果,如下所示:

public CustomSettings GetInitPath()
{
    XmlSerializer _mySerializer = new XmlSerializer(typeof(CustomSettings));
    FileStream    myFstream     = new FileStream(@"U:\Alex\prefs.xml", FileMode.Open);
    var cs                      = (CustomSettings)_mySerializer.Deserialize(myFstream);
    myFstream.Close();

    return cs;
}

另一个观察结果:在可能的情况下使用using来包装一次性资源会更好。如果你这样做,你的方法将如下所示:

public CustomSettings GetInitPath()
{
    var serializer = new XmlSerializer(typeof(CustomSettings));

    using (var myFstream = new FileStream(@"U:\Alex\prefs.xml", FileMode.Open))
    {
        return (CustomSettings) serializer.Deserialize(myFstream);
    }
}

即使myFstream发生异常,也会关闭Deserialize()