Porównaj numery wersji bez używania funkcji podziału

124

Jak porównać numery wersji?

Na przykład:

x = 1,23,56,1487,5

y = 1,24,55,487,2

Sankar M
źródło
4
Jaki ma być wynik?
BoltClock
4
wersja z 5 częściami? Jeśli używasz typowej wersji 4-częściowej, możesz użyć klasy System.Version, która zawiera metody do porównywania wersji i analizowania ciągu wersji
psousa
1
Jakie są typy X i Y?
Gleno,
5
Gdy ktoś mówi: „Nie używać X, Yalbo Z”, to zawsze sprawia, że zastanawiam się, dlaczego. Dlaczego nie chcesz korzystać z tej splitfunkcji? Ta splitfunkcja wydaje się dobrym sposobem na zrobienie tego, jeśli nie zamierzasz używać tej System.Versionklasy.
Bob2Chiv

Odpowiedzi:

294

Czy możesz użyć klasy Version?

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

Posiada interfejs IComparable. Pamiętaj, że to nie zadziała z pięcioczęściowym ciągiem wersji, takim jak pokazałeś (czy to naprawdę jest twoja wersja?). Zakładając, że dane wejściowe są ciągami, oto działający przykład z normalnym ciągiem 4-częściowej wersji .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;

    }
}
John D.
źródło
5
Tylko jeśli wersja składa się z 2-4 części
nazwa użytkownika
@dev_Boston tylko jeden wyjątek ... po prostu zrób z tymi wartościami v1 = 1.0001 i v2 = 1.1. daje mi to równość.
Sankar M
8
Tak, ciągi wersji nie są ciągami dziesiętnymi, a poprzedzanie zer na części numeru wersji jest nieistotne. Innymi słowy, „00001” jest równe „1” w drugiej części ciągu wersji.
JohnD,
8
Możesz porównać bardziej czytelnie Version.Parse(v1) < Version.Parse(v2), ponieważ operator >(Version v1, Version v2)jest zaimplementowany.
Andrey Moiseev
Należy pamiętać, że Version.Parse („6.0.0”) jest mniejsze niż (<) Version.Parse („6.0.0.0”) (tj. NIE są równe). Debug.Assert(new Version("6.0.0") < new Version("6.0.0.0"));
adospace
13

Jeśli możesz żyć ze schematem major.minor.build.revision, możesz użyć klasy .Net Version . W przeciwnym razie musiałbyś zaimplementować jakiś rodzaj analizy od lewej do prawej i kontynuować, aż pojawi się różnica lub zwrot, że dwie wersje są równe.

Andreas
źródło
7

Oprócz odpowiedzi @JohnD może zaistnieć potrzeba porównania tylko częściowych numerów wersji bez używania Split („.”) Lub innego ciągu <-> int konwersji bloat. Właśnie napisałem metodę rozszerzenia CompareTo z 1 dodatkowym argumentem - liczbą znaczących części numeru wersji do porównania (od 1 do 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; 
    }
}
też
źródło
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;
    }
user3790307
źródło
14
Uważaj, że to zwróci równecompareVersion("1.3", "1.3.1")
Ozgur Ozcitak
1

Jeśli z jakiegoś powodu nie możesz bezpośrednio użyć metody porównania wersji (np. W scenariuszu klient-serwer), innym podejściem jest wyodrębnienie długiej liczby z wersji, a następnie porównanie ich ze sobą. Jednak numer musi mieć następujący format: dwie cyfry dla numeru głównego, drugorzędnego i rewizji oraz cztery dla numeru kompilacji.

Jak wyodrębnić numer wersji:

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

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

A potem gdzie indziej możesz po prostu porównać:

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

Uwaga: zainstalowana wersja jest wcześniej wyodrębnioną długą liczbą

Fabian Bigler
źródło
Aby wszystkie cyfry miały 3 miejsca, kod powinien wyglądać tak: „wersja.Major * 1000000000L + wersja.Mniejsza * 1000000L + wersja.Zbuduj * 1000L +
wersja.Rewizja
1
@StefHeyenrath Zgadza się, możesz dostosować powyższy kod do własnych potrzeb.
Fabian Bigler