Sealed表示不能派生子类的类;您的第二个错误必须是指无法创建特定的子类化尝试,而不是尝试创建密封类本身的实例。
不为类声明任何公共构造函数的主要原因是为了控制其实例的创建。如前所述,这是在单例模式中完成的。这也可以用于工厂模式实现。在我的游戏引擎中,我为具有多个版本的定义文件的共享部分的各种解析器执行此操作。有时我将所有构造函数设为私有;有时是内部的;有时受保护以提供不同的控制机制。在这些情况下,我实际上都没有强制执行单例模式。
这是此用法的摘录:
internal abstract class AbstractParser {
protected TextReader Reader { get; set; }
// etc.
}
internal abstract class MapParser : AbstractParser, IParser<IMapDefinition> {
public abstract IMapDefinition Parse();
protected internal MapParser(TextReader reader) : this() {
Reader = reader;
}
public IMapDefinition Parse(Func<MapHeader, string[], int[][],
HexsideData[,], List<IHpsPlaceName>, int, IMapDefinition> factory
) {
var header = ParseMapHeader(1);
var terrain = ParseTerrain(header.Size);
var elevations = ParseElevation(header.Size);
var feature = ParseFeatures( header.Size);
var placeNames = ParsePlaceNames();
return factory(header, terrain, elevations, feature, placeNames, MaxElevationLevel);
}
// etc.
}
internal class MapV1Parser : MapParser {
internal MapV1Parser(TextReader reader) : base(reader) {}
public override IMapDefinition Parse() {
return base.Parse((h,t,e,f,p,xe) => (new MapDefinitionV1(h,t,e,f,p,xe)));
}
}
internal class MapV2Parser : MapParser {
private readonly Regex regexHeaderLine3;
internal MapV2Parser(TextReader reader) : base(reader) {
regexHeaderLine3 = new Regex(@"^([-]?[0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-1])$",
RegexOptions.None);
}
public override IMapDefinition Parse() {
return base.Parse((h,t,e,f,p,xe) => (new MapDefinitionV2(h,t,e,f,p,xe)));
}
protected override Line3 ParseHeaderLine3() {
/* Definition override for V3 */
}
}
此基础结构允许在读取第一行后选择适当的 MapParser,如下所示:
internal static IParser<IMapDefinition> GetMapParser(TextReader reader) {
string line = reader.ReadLine();
short version;
if (!short.TryParse(line, out version))
Utils.ThrowInvalidDataException("MapParser",1,"Header","Non-integer version number",null,line);
switch(version) {
case 1: return new MapV1Parser(reader);
case 2: return new MapV2Parser(reader);
default: Utils.ThrowInvalidDataException("MapParser",1,"Header","Unknown version number",
null,version);
return null;
}
}