不同版本解析文件不同
Parse file differently upon different version
编辑:我对此进行了一些研究,但未能找到解决方案!
我正在从 XML 文件中读取配置。
配置的布局是为特定版本设置的。
这个版本在XML的第一行,方便提取
我想知道的是,实际解析此 file/get 另一种方法的最佳方法是什么,它基于版本(所有 4 个元素,Major、Minor、Build 和 Revision)。
现在我想到了这个:
switch (version.Major)
{
case 0:
switch (version.Minor)
{
case 0:
switch (version.Build)
{
case 0:
switch (version.Revision)
{
case 0:
return VersionNone(doc);
}
break;
}
break;
}
break;
}
throw new NotImplementedException();
但我觉得这(一点也不)优雅,我觉得有更好的方法来做到这一点。
谁能帮忙?
对于这样的事情,我很想建立一个动作字典
编辑:更新为包含文档参数以响应 OP
的评论
Dictionary<string, Action<XmlDocument>> versionSpecificMethods = new Dictionary<string, Action<XmlDocument>>{
{"1.0.0.0", DoStuff1},
{"1.2.3.4", DoStuff2},
{"3.1.7.182", DoStuff3}};
private void RunMethodForVersion(string version, XmlDocument someXmlDoc)
{
var codeToRun = versionSpecificMethods[version];
codeToRun.Invoke(someXmlDoc);
}
private static void DoStuff1(XmlDocument doc)
{
// Insert user code here
}
如果你想在版本之间共享代码,你可以尝试使用继承:
interface IConfig
{
string GetConnectionString();
string GetUserSettings();
int GetDelay();
}
class Version_1 : IConfig
{
public virtual string GetConnectionString() { ... }
public virtual string GetUserSettings { ... }
public virtual int GetDelay();
}
class Version_1_1 : Version_1
{
// Changed UserSetttings and delay in xml
public override GetUserSettings { ... }
public override int GetDelay { ... }
}
class Version_1_1_4 : Version_1_1
{
// Changed delay in xml
public override int GetDelay { ... }
}
现在您需要根据文件的版本创建所需的配置实例。
您可以试试这个,例如 :(
enum Version {
Major = 0,
Build = 1,
Revision = 2
}
public class MyApp {
static Dictionary<Version, object> versionManager = new Dictionary<Version, object> {
{Version.Major, new Major() },
{Version.Build, new Build() },
{Version.Revision, new Revision() }
};
public static object Run( int v, XmlDocument xmlDoc ) {
try {
Version version = (Version)v;
var classObj = versionManager[version];
return classObj.GetType().GetMethod("Parse").Invoke(classObj, new object[] { xmlDoc });//System.Reflection;
} catch {
throw new NotImplementedException();
}
}
}
//Major = 0
class Major {
public Major( ) { }
public string Parse( XmlDocument xmlDoc ) {
return "DONE";
}
}
//Build = 1
class Build {
public Build( ) { }
public string Parse( XmlDocument xmlDoc ) {
return "DONE";
}
}
//Revision = 2
class Revision {
public Revision( ) { }
public string Parse( XmlDocument xmlDoc ) {
return "DONE";
}
}
使用==>
MyApp.Run(1/*Version==>Build*/, new XmlDocument());
基于@Andy-P 的 ,但查找 'most recent' 版本而不是确切版本:
using ParserFunction = System.Func<object,object>;
public static class ParserFactory
{
private static System.Collections.Generic.SortedDictionary<Version, ParserFunction> Parsers
= new System.Collections.Generic.SortedDictionary<Version, ParserFunction>();
public static void SetParser(Version version, ParserFunction parser)
{
if (Parsers.ContainsKey(version)) Parsers[version] = parser;
else Parsers.Add(version, parser);
}
public static ParserFunction GetParser(Version version)
{
if (Parsers.Count == 0) return null;
Version lastKey = null;
foreach ( var key in Parsers.Keys)
{
if (version.CompareTo(key) < 0)
{
if ( lastKey == null ) lastKey = key;
break;
}
lastKey = key;
if (version.CompareTo(key) == 0) break;
}
return Parsers[lastKey];
}
}
编辑:我对此进行了一些研究,但未能找到解决方案!
我正在从 XML 文件中读取配置。 配置的布局是为特定版本设置的。 这个版本在XML的第一行,方便提取
我想知道的是,实际解析此 file/get 另一种方法的最佳方法是什么,它基于版本(所有 4 个元素,Major、Minor、Build 和 Revision)。
现在我想到了这个:
switch (version.Major)
{
case 0:
switch (version.Minor)
{
case 0:
switch (version.Build)
{
case 0:
switch (version.Revision)
{
case 0:
return VersionNone(doc);
}
break;
}
break;
}
break;
}
throw new NotImplementedException();
但我觉得这(一点也不)优雅,我觉得有更好的方法来做到这一点。
谁能帮忙?
对于这样的事情,我很想建立一个动作字典
编辑:更新为包含文档参数以响应 OP
的评论 Dictionary<string, Action<XmlDocument>> versionSpecificMethods = new Dictionary<string, Action<XmlDocument>>{
{"1.0.0.0", DoStuff1},
{"1.2.3.4", DoStuff2},
{"3.1.7.182", DoStuff3}};
private void RunMethodForVersion(string version, XmlDocument someXmlDoc)
{
var codeToRun = versionSpecificMethods[version];
codeToRun.Invoke(someXmlDoc);
}
private static void DoStuff1(XmlDocument doc)
{
// Insert user code here
}
如果你想在版本之间共享代码,你可以尝试使用继承:
interface IConfig
{
string GetConnectionString();
string GetUserSettings();
int GetDelay();
}
class Version_1 : IConfig
{
public virtual string GetConnectionString() { ... }
public virtual string GetUserSettings { ... }
public virtual int GetDelay();
}
class Version_1_1 : Version_1
{
// Changed UserSetttings and delay in xml
public override GetUserSettings { ... }
public override int GetDelay { ... }
}
class Version_1_1_4 : Version_1_1
{
// Changed delay in xml
public override int GetDelay { ... }
}
现在您需要根据文件的版本创建所需的配置实例。
您可以试试这个,例如 :(
enum Version {
Major = 0,
Build = 1,
Revision = 2
}
public class MyApp {
static Dictionary<Version, object> versionManager = new Dictionary<Version, object> {
{Version.Major, new Major() },
{Version.Build, new Build() },
{Version.Revision, new Revision() }
};
public static object Run( int v, XmlDocument xmlDoc ) {
try {
Version version = (Version)v;
var classObj = versionManager[version];
return classObj.GetType().GetMethod("Parse").Invoke(classObj, new object[] { xmlDoc });//System.Reflection;
} catch {
throw new NotImplementedException();
}
}
}
//Major = 0
class Major {
public Major( ) { }
public string Parse( XmlDocument xmlDoc ) {
return "DONE";
}
}
//Build = 1
class Build {
public Build( ) { }
public string Parse( XmlDocument xmlDoc ) {
return "DONE";
}
}
//Revision = 2
class Revision {
public Revision( ) { }
public string Parse( XmlDocument xmlDoc ) {
return "DONE";
}
}
使用==>
MyApp.Run(1/*Version==>Build*/, new XmlDocument());
基于@Andy-P 的
using ParserFunction = System.Func<object,object>;
public static class ParserFactory
{
private static System.Collections.Generic.SortedDictionary<Version, ParserFunction> Parsers
= new System.Collections.Generic.SortedDictionary<Version, ParserFunction>();
public static void SetParser(Version version, ParserFunction parser)
{
if (Parsers.ContainsKey(version)) Parsers[version] = parser;
else Parsers.Add(version, parser);
}
public static ParserFunction GetParser(Version version)
{
if (Parsers.Count == 0) return null;
Version lastKey = null;
foreach ( var key in Parsers.Keys)
{
if (version.CompareTo(key) < 0)
{
if ( lastKey == null ) lastKey = key;
break;
}
lastKey = key;
if (version.CompareTo(key) == 0) break;
}
return Parsers[lastKey];
}
}