Порівняйте номери версій без використання розділеної функції


124

Як порівняти номери версій?

Наприклад:

х = 1,23,56,1487,5

у = 1,24,55,487,2


4
Яким ви хочете, щоб результат був?
BoltClock

4
версія з 5 частинами? Якщо ви використовували типову 4-частинну версію, ви можете використовувати клас System.Version, який включає методи порівняння версій та розбору рядка версії
psousa

1
Які типи х і у?
Глено

5
Всякий раз , коли хто - то говорить : «Не використовувати X, Yабо Z", це завжди змушує мене задатися питанням, чому. Чому ви не хочете використовувати цю splitфункцію? Ця splitфункція здається хорошим способом зробити це, якщо ви не збираєтесь використовувати System.Versionклас.
Bob2Chiv

Відповіді:


294

Чи можете ви використовувати клас Версія?

http://msdn.microsoft.com/en-us/library/system.version.aspx

Він має інтерфейс, що не можна порівняти. Пам’ятайте, що це не буде працювати з 5-частинною рядком версії, як ви показали (це справді ваша версія версії? Припустимо, що ваші входи - це рядки, ось робочий зразок із звичайною. NET-частиною рядком версії:

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. це дає мені рівне.
Санкар М

8
Так, рядки версії не є десятковими рядками, і попередньо додані нулі до частини номера версії не мають значення. Іншими словами, "00001" дорівнює "1" у другій частині рядка версії.
JohnD

8
Ви можете порівняти більш зрозуміло як Version.Parse(v1) < Version.Parse(v2), тому що operator >(Version v1, Version v2)це реалізовано.
Андрій Мойсеєв

Майте на увазі, що Version.Parse ("6.0.0") менше (<) Версія.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 може виникнути потреба порівняти лише часткові номери версій без використання розділеного ('.') Або іншого рядка <-> int перетворення конвертів. Я щойно написав метод розширення Порівняти до 1 додаткового аргументу - кількість значущих частин номера версії для порівняння (між 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

Якщо з якихось причин вам заборонено використовувати метод порівняння Версії безпосередньо (наприклад, у сценарії клієнт-сервер), інший підхід полягає в витягуванні довгого числа з версії, а потім порівнянні чисел між собою. Однак номер повинен мати наступний формат: Двозначні цифри для мажору, мінору та версії та чотири для збірки.

Як отримати номер версії:

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

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

І тоді десь ще можна просто порівняти:

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

Примітка: встановленийVersion - це раніше вилучений довгий номер


Щоб дати всім цифрам 3 місця, код насправді повинен бути: "версія.Major * 1000000000L + версія.Minor * 1000000L + версія.Build * 1000L + version.Revision"
Стеф Хейенрат

1
@StefHeyenrath Це правильно, не соромтесь коригувати вищевказаний код під власні потреби.
Фабіан Біглер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.