是否有一种不太复杂的比较文件版本的方法?

时间:2014-02-20 16:52:27

标签: c# boolean logic boolean-logic boolean-operations

我编写了一个函数来比较客户端当前拥有的文件版本与服务器上文件的最新版本。客户端将“quad”(Major.Minor.Build.Private)版本号作为字符串传递给服务器,然后服务器使用FileVersionInfo:

// clientFileVersion will be in "quad" format, a la "3.1.4.1"
private bool ServerFileIsNewer(string clientFileVersion, FileVersionInfo serverFile)
{
    // Don't say I never learned nuthin' from Steve McConnell
    const int MAJOR_INDEX = 0;
    const int MINOR_INDEX = 1;
    const int BUILD_INDEX = 2;
    const int PRIVATE_INDEX = 3;

    string[] versionStrArray = clientFileVersion.Split('.');
    int FileMajorPartClient;
    Int32.TryParse(versionStrArray[MAJOR_INDEX], out FileMajorPartClient);
    int FileMinorPartClient;
    Int32.TryParse(versionStrArray[MINOR_INDEX], out FileMinorPartClient);
    int FileBuildPartClient;
    Int32.TryParse(versionStrArray[BUILD_INDEX], out FileBuildPartClient);
    int FilePrivatePartClient;
    Int32.TryParse(versionStrArray[PRIVATE_INDEX], out FilePrivatePartClient);

    int FileMajorPartServer = serverFile.FileMajorPart;
    int FileMinorPartServer = serverFile.FileMinorPart;
    int FileBuildPartServer = serverFile.FileBuildPart;
    int FilePrivatePartServer = serverFile.FilePrivatePart;

    return ((FileMajorPartClient < FileMajorPartServer) ||
           ((FileMajorPartClient == FileMajorPartServer) && (FileMinorPartClient < FileMinorPartServer)) ||
           ((FileMinorPartClient == FileMinorPartServer) && (FileBuildPartClient < FileBuildPartServer)) ||
           ((FileBuildPartClient == FileBuildPartServer) && (FilePrivatePartClient < FilePrivatePartServer)));
}

但后来我意识到,如果客户端版本为2.1.1.1且服务器版本为1.1.2.1,则我的megaboolean return语句将失败

IOW,它表示服务器版本更新,实际上(当然)它不是。

然后我想我会添加更多的布尔逻辑,例如:

if   (FileMajorClient > FileMajorServer) || 
     ((FileMajorClient == FileMajorServer) && (FileMinorClient > FileMinorServer)) ||
     ((FileMajorClient == FileMajorServer) && (FileMinorClient == FileMinorServer) && (FileBuildClient > FileBuildServer))
{
    return false;
}
else
{
    return ((FileMajorPartClient < FileMajorPartServer) ||
           ((FileMajorPartClient == FileMajorPartServer) && (FileMinorPartClient < FileMinorPartServer)) ||
           ((FileMinorPartClient == FileMinorPartServer) && (FileBuildPartClient < FileBuildPartServer)) ||
           ((FileBuildPartClient == FileBuildPartServer) && (FilePrivatePartClient < FilePrivatePartServer)));
}

...但是正如你所看到的,它正变成疯狂/意大利面乱的大球。

必须有一种更好,更容易,更易于理解/可维护的方式来比较两个文件版本。但是/怎么样?

更新

使用Servy的答案,现在就是这个方法:

private bool ServerFileIsNewer(string clientFileVersion, FileVersionInfo serverFile)
{
    Version client = new Version(clientFileVersion);
    Version server = new Version(string.Format("{0}.{1}.{2}.{3}", serverFile.FileMajorPart, serverFile.FileMinorPart, serverFile.FileBuildPart, serverFile.FilePrivatePart));
    return server > client;
}

作为一个不吹哨的哨子清洁,简洁如Joe Friday的梦想见证,和Grace Kelley一样优雅。

2 个答案:

答案 0 :(得分:16)

使用Version类:

Version first = new Version("1.1.2.1");
Version second = new Version("2.1.1.1");
bool b = first >= second;

答案 1 :(得分:4)

Servy's answer是你应该选择的那个。

但是,对于其他情况,当你有嵌套标准并且你没有已经实现比较的类的好处时,最直接的方法是使用多个条件并尽快“早出”您可以。例如,在检查版本时,您可以执行此操作:

if (FileMajorClient > FileMajorServer)
    return false;
if (FileMajorClient < FileMajorServer)
    return true;

// Major versions are equal, now do the same thing for minor part
if (FileMinorClient != FileMinorServer)
    return (FileMinorClient < FileMinorServer);

请注意,主要版本检查的编写方式与次要版本检查的编写方式相同。这只是编写相同逻辑的两种不同方式。

然后,您可以为其余每个部分执行此操作。

if (FileBuildPartClient != FileBuildPartServer)
    return (FileBuildPartClient < FileBuildPartServer);

return (FilePrivatePartClient <= FilePrivatePartServer);

在每一步中,您都消除了客户端和服务器版本不匹配的情况。

这不像编写单一条件语句那样“聪明”,但它易于理解且易于证明是正确的。