避免XML可序列化类中的重复代码

时间:2014-09-08 14:55:46

标签: c# xml-serialization dry

我有两个代码非常相似的Serializable类。实际上,除了调用特定构造函数的部分之外,序列化代码是相同的。

有没有办法创建一个公共类来包含公共部分,以便特定的类(子类?)只能实现构造函数部分?我可以想到仿制药,工厂模式,但无法弄清楚如何去做。

// Fictitious classes

[Serializable]
public class FlightParameters {

    public double MaxHeight { get; set; }
    pulbic double MaxSpeedKmPerHour { get; set; }

    public static FlightParameters Load(String fname) {
        FlightParameters result;
        using (var fs = new FileStream(fname, FileMode.OpenOrCreate)) {
            var serializer = new XmlSerializer(typeof(FlightParameters));
            try {
                result = (FlightParameters)serializer.Deserialize(fs);
            }
            // catch "file not found"
            catch (InvalidOperationException) {
                result = new FlightParameters() {
                    MaxHeight = 30000;
                    MaxSpeedKmPerHour = 1500;
                }
                serializer.Serialize(fs, result);
            }
            return result;
        }
    }

}


[Serializable]
public class SailingParameters {

    public double MaxDepth { get; set; }
    pulbic double MaxSpeedKnots { get; set; }

    public static SailingParameters Load(String fname) {
        SailingParameters result;
        using (var fs = new FileStream(fname, FileMode.OpenOrCreate)) {
            var serializer = new XmlSerializer(typeof(SailingParameters));
            try {
                result = (SailingParameters)serializer.Deserialize(fs);
            }
            // catch "file not found"
            catch (InvalidOperationException) {
                result = new SailingParameters() {
                    MaxDepth = 13000;
                    MaxSpeedKnots = 15;
                }
                serializer.Serialize(fs, result);
            }
            return result;
        }
    }

}

用法:

FlightParameters _fparam = FlightParameters.Load(somePath);
SailingParameters _sparam = SailingParameters.Load(someOtherPath);

1 个答案:

答案 0 :(得分:1)

我能看到的最简单的方法就是:

static class XmlUtils {
    public static T Load<T>(string filename, Func<T> onMissing = null)
        where T : class, new()
    {
        using (var fs = File.OpenRead(filename)) {
            var serializer = new XmlSerializer(typeof(T));
            try {
                return (T)serializer.Deserialize(fs);
            } catch (InvalidOperationException) { // catch "file not found"
                return onMissing == null ? new T() : onMissing();
            }
        }
    }
}

允许类似的内容;

public static SailingParameters Load(string filename) {
    return XmlUtils.Load<SailingParameters>(filename, () => new SailingParameters {
        MaxDepth = 13000;
        MaxSpeedKnots = 15;
    });
}