Confronta i numeri di versione senza utilizzare la funzione divisa


124

Come faccio a confrontare i numeri di versione?

Per esempio:

x = 1.23.56.1487.5

y = 1.24.55.487.2


4
Cosa vuoi che sia il risultato?
BoltClock

4
una versione con 5 parti? Se si utilizzava la tipica versione in 4 parti, è possibile utilizzare la classe System.Version, che include metodi per confrontare le versioni e analizzare la stringa di versione
psousa,

1
Quali sono i tipi di xey?
Gleno,

5
Ogni volta che qualcuno dice "Non usare X, Yo Z", mi viene sempre da chiedermi perché. Perché non vuoi usare la splitfunzione? La splitfunzione sembra un buon modo per farlo se non hai intenzione di usare la System.Versionclasse.
Bob2Chiv,

Risposte:


294

Puoi usare la classe Version?

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

Ha un'interfaccia IComparable. Ricorda che non funzionerà con una stringa di versione in 5 parti come hai mostrato (è davvero la stringa della versione?). Supponendo che i tuoi input siano stringhe, ecco un esempio funzionante con la normale stringa di versione .NET in 4 parti:

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
Solo se la versione è composta da 2-4 parti
nome utente

@dev_Boston solo un'eccezione ... basta fare con questi valori v1 = 1.0001 e v2 = 1.1 .it mi dà uguale.
Sankar M,

8
Sì, le stringhe di versione non sono stringhe decimali e anteporre zero a una parte del numero di versione è irrilevante. In altre parole, "00001" è uguale a "1" nella seconda parte della stringa di versione.
JohnD,

8
Puoi confrontare più facilmente come Version.Parse(v1) < Version.Parse(v2), perché operator >(Version v1, Version v2)è implementato.
Andrey Moiseev,

Tenere presente che Version.Parse ("6.0.0") è inferiore a (<) Version.Parse ("6.0.0.0") (ovvero NON sono uguali). Debug.Assert(new Version("6.0.0") < new Version("6.0.0.0"));
Adospace

13

Se riesci a convivere con lo schema major.minor.build.revision puoi usare la classe .Net Version . Altrimenti dovresti implementare una sorta di analisi da sinistra a destra e continuare fino a quando non hai una differenza o restituisci che due versioni sono uguali.


7

Oltre alla risposta di @JohnD, potrebbe essere necessario confrontare solo i numeri di versione parziali senza utilizzare Split ('.') O altra stringa <-> bloat di conversione int. Ho appena scritto un metodo di estensione CompareTo con 1 argomento aggiuntivo: il numero di parti significative del numero di versione da confrontare (tra 1 e 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
Attenzione che questo ritorno sarebbe uguale acompareVersion("1.3", "1.3.1")
Ozgur Ozcitak

1

Se per qualche motivo non ti è consentito utilizzare direttamente il metodo di confronto della versione (ad esempio in uno scenario client-server), un altro approccio è quello di estrarre un numero lungo dalla versione e quindi confrontare i numeri tra loro. Tuttavia, il numero deve avere il seguente formato: due cifre per Major, Minor e Revision e quattro per Build.

Come estrarre il numero di versione:

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

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

E poi da qualche altra parte puoi solo confrontare:

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

Nota: la versione installata è un numero lungo estratto in precedenza


Per assegnare a 3 cifre tutte le cifre, il codice dovrebbe essere effettivamente: "version.Major * 1000000000L + version.Minor * 1000000L + version.Build * 1000L + version.Revision"
Stef Heyenrath,

1
@StefHeyenrath È corretto, sentiti libero di adattare il codice sopra alle tue esigenze.
Fabian Bigler,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.