比较版本号而不使用拆分功能


124

如何比较版本号?

例如:

x = 1.23.56.1487.5

y = 1.24.55.487.2


4
您希望结果是什么?
BoltClock

4
有5个部分的版本?如果您使用的是典型的4部分版本,则可以使用System.Version类,该类包括比较版本和解析版本字符串的方法
psousa 2011年

1
x和y的类型是什么?
Gleno

5
每当有人说“请不要使用XY或者Z”,它总是让我不知道为什么。为什么不想使用该split功能?split如果您不打算使用System.Version该类,则该函数似乎是执行此操作的好方法。
Bob2Chiv 2011年

Answers:


294

可以使用Version类吗?

http://msdn.microsoft.com/zh-CN/library/system.version.aspx

它具有IComparable接口。请注意,这不适用于您显示的5部分版本字符串(这真的是您的版本字符串吗?)。假设您输入的是字符串,这是正常的.NET 4部分版本字符串的工作示例:

static class Program
{
    static void Main()
    {
        string v1 = "1.23.56.1487";
        string v2 = "1.24.55.487";

        var version1 = new Version(v1);
        var version2 = new Version(v2);

        var result = version1.CompareTo(version2);
        if (result > 0)
            Console.WriteLine("version1 is greater");
        else if (result < 0)
            Console.WriteLine("version2 is greater");
        else
            Console.WriteLine("versions are equal");
        return;

    }
}

5
仅当版本由2-4部分组成时
用户名

@dev_Boston只有一个例外...只需使用这些值v1 = 1.0001和v2 = 1.1即可。
Sankar M

8
是的,版本字符串不是十进制字符串,并且在版本号的一部分前面加零是无关紧要的。换句话说,版本字符串的第二部分中的“ 00001”等于“ 1”。
JohnD

8
您可以将进行比较比较可读Version.Parse(v1) < Version.Parse(v2),因为operator >(Version v1, Version v2)已实现。
安德烈·莫伊谢夫

请注意,Version.Parse(“ 6.0.0”)小于(<)Version.Parse(“ 6.0.0.0”)(即不相等)。Debug.Assert(new Version("6.0.0") < new Version("6.0.0.0"));
adospace

13

如果可以使用major.minor.build.revision方案,则可以使用.Net 版本类。否则,您将必须实现从左到右的某种解析,然后继续直到您有区别或返回两个版本相等为止。


7

除了@JohnD的答案外,可能还需要仅比较部分版本号,而不使用Split('。')或其他字符串<-> int转换膨胀。我刚刚编写了一个扩展方法CompareTo,带有一个附加参数-要比较的版本号的重要部分的数量(介于1和4之间)。

public static class VersionExtensions
{
    public static int CompareTo(this Version version, Version otherVersion, int significantParts)
    {
        if(version == null)
        {
            throw new ArgumentNullException("version");
        }
        if(otherVersion == null)
        {
            return 1;
        }

        if(version.Major != otherVersion.Major && significantParts >= 1)
            if(version.Major > otherVersion.Major)
                return 1;
            else
                return -1;

        if(version.Minor != otherVersion.Minor && significantParts >= 2)
            if(version.Minor > otherVersion.Minor)
                return 1;
            else
                return -1;

        if(version.Build != otherVersion.Build && significantParts >= 3)
            if(version.Build > otherVersion.Build)
                return 1;
            else
                return -1;

        if(version.Revision != otherVersion.Revision && significantParts >= 4)
            if(version.Revision > otherVersion.Revision)
                return 1;
            else
                return -1;

        return 0; 
    }
}

4
public int compareVersion(string Version1,string Version2)
    {
        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"([\d]+)");
        System.Text.RegularExpressions.MatchCollection m1 = regex.Matches(Version1);
        System.Text.RegularExpressions.MatchCollection m2 = regex.Matches(Version2);
        int min = Math.Min(m1.Count,m2.Count);
        for(int i=0; i<min;i++)
        {
            if(Convert.ToInt32(m1[i].Value)>Convert.ToInt32(m2[i].Value))
            {
                return 1;
            }
            if(Convert.ToInt32(m1[i].Value)<Convert.ToInt32(m2[i].Value))
            {
                return -1;
            }               
        }
        return 0;
    }

14
当心这将返回等于compareVersion("1.3", "1.3.1")
Ozgur Ozcitak

1

如果由于某种原因不允许您直接使用版本的比较方法(例如,在客户端-服务器方案中),则另一种方法是从版本中提取一个长数字,然后将这些数字相互比较。但是,该数字必须具有以下格式:“主要”,“次要”和“修订”分别为两位数和“内部版本”为4位。

如何提取版本号:

var version = Assembly.GetExecutingAssembly().GetName().Version;

long newVersion = version.Major * 1000000000L + 
                   version.Minor * 1000000L + 
                   version.Build * 1000L + 
                   version.Revision;

然后您可以在其他地方进行比较:

if(newVersion > installedVersion)
{
  //update code
}

注意:installedVersion是以前提取的长整数


要给所有数字3位,代码实际上应该是:“ version.Major * 1000000000L + version.Minor * 1000000L + version.Build * 1000L + version.Revision”
Stef Heyenrath

1
@StefHeyenrath没错,可以根据自己的需要随意调整上面的代码。
法比安·比格勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.