26

这是我的代码,它采用“1、5、0、4”或“1.5.0.4”形式的两个版本标识符,并确定哪个是较新的版本。

请提出建议或改进!

    /// <summary>
    /// Compares two specified version strings and returns an integer that 
    /// indicates their relationship to one another in the sort order.
    /// </summary>
    /// <param name="strA">the first version</param>
    /// <param name="strB">the second version</param>
    /// <returns>less than zero if strA is less than strB, equal to zero if
    /// strA equals strB, and greater than zero if strA is greater than strB</returns>
    public static int CompareVersions(string strA, string strB)
    {
        char[] splitTokens = new char[] {'.', ','};
        string[] strAsplit = strA.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
        string[] strBsplit = strB.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
        int[] versionA = new int[4];
        int[] versionB = new int[4];

        for (int i = 0; i < 4; i++)
        {
            versionA[i] = Convert.ToInt32(strAsplit[i]);
            versionB[i] = Convert.ToInt32(strBsplit[i]);
        }

        // now that we have parsed the input strings, compare them
        return RecursiveCompareArrays(versionA, versionB, 0);
    }

    /// <summary>
    /// Recursive function for comparing arrays, 0-index is highest priority
    /// </summary>
    private static int RecursiveCompareArrays(int[] versionA, int[] versionB, int idx)
    {
        if (versionA[idx] < versionB[idx])
            return -1;
        else if (versionA[idx] > versionB[idx])
            return 1;
        else
        {
            Debug.Assert(versionA[idx] == versionB[idx]);
            if (idx == versionA.Length - 1)
                return 0;
            else
                return RecursiveCompareArrays(versionA, versionB, idx + 1);
        }
    }

@达伦·科普

版本类不处理格式 1.0.0.5 的版本。

4

4 回答 4

40

使用版本类。

Version a = new Version("1.0.0.0");
Version b = new Version("2.0.0.0");

Console.WriteLine(string.Format("Newer: {0}", (a > b) ? "a" : "b"));
// prints b
于 2008-08-27T15:50:17.330 回答
31

System.Version类不支持其中包含逗号的版本,因此 Darren Kopp 提出的解决方案是不够的。

这是一个尽可能简单的版本(但并不简单)。

它使用System.Version,但通过在比较之前进行搜索替换来实现与“1、2、3、4”等版本号的兼容性。

    /// <summary>
    /// Compare versions of form "1,2,3,4" or "1.2.3.4". Throws FormatException
    /// in case of invalid version.
    /// </summary>
    /// <param name="strA">the first version</param>
    /// <param name="strB">the second version</param>
    /// <returns>less than zero if strA is less than strB, equal to zero if
    /// strA equals strB, and greater than zero if strA is greater than strB</returns>
    public static int CompareVersions(String strA, String strB)
    {
        Version vA = new Version(strA.Replace(",", "."));
        Version vB = new Version(strB.Replace(",", "."));

        return vA.CompareTo(vB);
    }

该代码已经过测试:

    static void Main(string[] args)
    {
        Test("1.0.0.0", "1.0.0.1", -1);
        Test("1.0.0.1", "1.0.0.0", 1);
        Test("1.0.0.0", "1.0.0.0", 0);
        Test("1, 0.0.0", "1.0.0.0", 0);
        Test("9, 5, 1, 44", "3.4.5.6", 1);
        Test("1, 5, 1, 44", "3.4.5.6", -1);
        Test("6,5,4,3", "6.5.4.3", 0);

        try
        {
            CompareVersions("2, 3, 4 - 4", "1,2,3,4");
            Console.WriteLine("Exception should have been thrown");
        }
        catch (FormatException e)
        {
            Console.WriteLine("Got exception as expected.");
        }

        Console.ReadLine();
    }

    private static void Test(string lhs, string rhs, int expected)
    {
        int result = CompareVersions(lhs, rhs);
        Console.WriteLine("Test(\"" + lhs + "\", \"" + rhs + "\", " + expected +
            (result.Equals(expected) ? " succeeded." : " failed."));
    }
于 2008-08-27T16:56:31.320 回答
1

好吧,由于您只有一个四元素数组,您可能只想不展开递归以节省时间。将数组作为参数传递会占用内存并给 GC 留下一团糟,以便稍后清理。

于 2008-08-27T15:48:44.433 回答
0

如果您可以假设版本字符串中的每个位置都只有一个数字(或至少是最后 3 个数字,您可以删除逗号或句点并进行比较……这会快得多……不那么健壮,但你并不总是需要那个。

public static int CompareVersions(string strA, string strB)
{
    char[] splitTokens = new char[] {'.', ','};
    string[] strAsplit = strA.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
    string[] strBsplit = strB.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
    int versionA = 0;
    int versionB = 0;
    string vA = string.Empty;
    string vB = string.Empty;

    for (int i = 0; i < 4; i++)
    {
        vA += strAsplit[i];
        vB += strBsplit[i];
        versionA[i] = Convert.ToInt32(strAsplit[i]);
        versionB[i] = Convert.ToInt32(strBsplit[i]);
    }

    versionA = Convert.ToInt32(vA);
    versionB = Convert.ToInt32(vB);

    if(vA > vB)
       return 1;
    else if(vA < vB)
       return -1;
    else
       return 0;  //they are equal
}

是的,我还假设这里有 4 个版本的地方......

于 2008-08-27T15:52:02.990 回答