在不同版本上以不同方式解析文件

时间:2018-03-21 14:57:02

标签: c# xml switch-statement version

编辑:我已对此做了一些研究,但未能找到解决方案!

我正在从XML文件中读取配置。 为某些版本设置配置的布局。 此版本位于XML的第一行,易于提取。

我想知道的是,实际解析此文件/获取另一种方法的最佳方法是什么,基于版本(所有4个元素,主要,次要,构建和修订)。

现在我已经想到了这个:

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();

但我发现这种优雅(根本没有),我觉得有更好的方法可以做到这一点。

任何可以提供帮助的人?

4 个答案:

答案 0 :(得分:8)

对于这样的事情,我很想建立行动词典

编辑:已更新,以包含文件参数以响应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
    }

答案 1 :(得分:3)

如果要在版本之间共享代码,可以尝试使用继承:

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 { ... }
}

现在您需要根据文件版本创建需要的配置实例。

答案 2 :(得分:3)

你可以试试这个:(

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";
    }
}

使用==&gt;

MyApp.Run(1/*Version==>Build*/, new XmlDocument());

答案 3 :(得分:1)

以@ Andy-P&#39; answer为基础,但寻找最近的&#39;版本而不是确切的版本:

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];
    }
}