C# 避免XML可序列化类中的重复代码
我有两个C# 避免XML可序列化类中的重复代码,c#,xml-serialization,dry,C#,Xml Serialization,Dry,我有两个Serializable类,它们的代码非常相似。实际上,除了调用特定构造函数的部分外,序列化代码是相同的 有没有办法创建一个包含公共部分的公共类,以便特定类(子类?)只能实现构造函数部分?我可以想到泛型,工厂模式,但不知道如何做到这一点 // Fictitious classes [Serializable] public class FlightParameters { public double MaxHeight { get; set; } pulbic dou
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);
我能看到的最简单的方法是:
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();
}
}
}
}
静态类XmlUtils{
公共静态T加载(字符串文件名,Func onMissing=null)
其中T:class,new()
{
使用(var fs=File.OpenRead(文件名)){
var serializer=newxmlserializer(typeof(T));
试一试{
返回(T)序列化程序。反序列化(fs);
}catch(InvalidOperationException){//catch“未找到文件”
返回onMissing==null?新的T():onMissing();
}
}
}
}
允许这样的事情
public static SailingParameters Load(string filename) {
return XmlUtils.Load<SailingParameters>(filename, () => new SailingParameters {
MaxDepth = 13000;
MaxSpeedKnots = 15;
});
}
publicstaticsailingparameters加载(字符串文件名){
返回XmlUtils.Load(文件名,()=>新的SailingParameters{
最大深度=13000;
MaxSpeedKnots=15;
});
}
实际上不显示任何构造函数;你是说加载方法吗?哦,您不需要[Serializable]
-XmlSerializer
根本不关心that@MarcGravell我添加了用法示例。没错,没有公共构造函数,但是可以看到在“catch”块中调用默认构造函数。我不确定我在这里做的事情是否正确,所以欢迎任何建议,包括另一种完全不同的方法。OpenOrCreate
也可能非常有害,注意-这可能会使你的磁盘充满空文件,不是吗?@marcgravel可能是的,但在我的程序的其他地方运行一些清理例程。对于这个特定的部分,我相信OpenOrCreate
是理想的行为。有趣!午饭后再测试一下,然后发布一些反馈@heltonbiker您甚至可能不需要
-我怀疑编译器可以从lambda-so返回XmlUtils.Load(filename,()=>new SailingParameters{…})推断出这一点代码>这里有一个问题:我的原始代码在catch参数中创建了一个新的默认对象,并在返回它之前将其序列化。若我返回一个返回对象的函数,那个么在返回它之前如何将其序列化到文件中?重要的是,它发生在XmlUtils
类中,以避免重复。@helton k-只捕获创建的对象,而不是返回它;连载;然后返回