26

これは私のコードで、「1、5、0、4」または「1.5.0.4」の形式の 2 つのバージョン識別子を取り、どちらが新しいバージョンであるかを判断します。

提案または改善をお願いします!

    /// <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

4 つの要素の配列しかないので、時間を節約するために再帰をアンロールしたいだけかもしれません。引数として配列を渡すと、メモリが消費され、GC が後でクリーンアップするために混乱が生じます。

于 2008-08-27T15:48:44.433 に答える
0

バージョン文字列の各場所が 1 つの数字 (または少なくとも最後の 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 に答える