问题:
基类中的静态方法无法覆盖,因此我无法编译此代码(如果可以,我的设计将得到解决):
public abstract class ParametersBase
{
public static abstract ParametersBase CreateDefault(); // THIS DOES NOT COMPILE!
}
public abstract class ParametersXml<T> where T : ParametersBase
{
public static T LoadOrDefault(string fname)
{
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.InvariantCulture;
T result;
var serializer = new XmlSerializer(typeof(T));
FileStream fs;
try
{
using (fs = new FileStream(fname, FileMode.Open, FileAccess.Read))
result = (T)serializer.Deserialize(fs);
}
catch (InvalidOperationException)
{
result = (T)typeof(T).GetMethod("CreateDefault").Invoke(null, new object[] { });
using (fs = new FileStream(fname, FileMode.Create, FileAccess.Read))
serializer.Serialize(fs, result);
}
return result;
}
}
背景:
我正在尝试使用泛型在一组子类中实现简单的XML持久性,这些子类表示这些行中的参数组:
Parameter
子类都有一些属性,这些属性在子类之间有所不同; LoadOrDefault
方法和一个实例Save
方法; 我甚至不确定这些应该是正确的合作,我的意思是,每个ParameterBase
都需要包裹&#34;通过ParametersXml<>
,可能正确的做法是通过继承将持久性代码封装在基类中
这是一个好方法吗?我错过了什么吗?
答案 0 :(得分:3)
只是详细说明评论中发生的事情。
将static
方法标记为abstract
会产生编译时错误。主要是因为你不能在一般意义上将多态性应用于抽象方法(永远不会有虚拟方法调用)。
此实例需要的是不将方法标记为static
。现在出现的问题是,人们无法确定是否可以获得T
的实例。但是,可以通过将类定义更改为:{/ 1>进一步约束T
以使构造函数不带参数来更改此值。
public abstract class ParametersXml<T> where T : ParametersBase, new()
现在catch
LoadOrDefault
可以说:
result = new T().CreateDefault();
注意这样做也更清晰,并且避免使用反射和脏类型转换。
编辑: 更进一步
正如@AlexeiLevenkov指出的那样 - 假设CreateDefault
应该返回自己类型的实例,并且无参数构造函数在其默认状态下设置T
。甚至可以完全消除CreateDefault
的需要,只需将无参数构造函数用作CreateDefault
,从而将catch处理程序中的行更改为:
result = new T();