Bandingkan nomor versi tanpa menggunakan fungsi split


124

Bagaimana cara membandingkan nomor versi?

Misalnya:

x = 1.23.56.1487.5

y = 1.24.55.487.2


4
Apa yang Anda inginkan hasilnya?
BoltClock

4
versi dengan 5 bagian? Jika Anda menggunakan versi 4 bagian yang khas, Anda bisa menggunakan kelas System.Version, yang mencakup metode untuk membandingkan versi dan mengurai string versi
psousa

1
Apa jenis x dan y?
Gleno

5
Setiap kali seseorang berkata "Jangan gunakan X, Yatau Z", itu selalu membuat saya bertanya-tanya mengapa. Mengapa Anda tidak ingin menggunakan splitfungsi ini? The splitFungsi tampaknya seperti cara yang baik untuk melakukan hal ini jika Anda tidak akan menggunakan System.Versionkelas.
Bob2Chiv

Jawaban:


294

Bisakah Anda menggunakan kelas Versi?

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

Ini memiliki antarmuka IComparable. Ketahuilah bahwa ini tidak akan berfungsi dengan string versi 5-bagian seperti yang Anda tunjukkan (apakah itu benar-benar string versi Anda?). Dengan asumsi input Anda adalah string, inilah sampel yang berfungsi dengan string versi .NET 4-bagian normal:

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
Hanya jika versi terdiri dari 2-4 bagian
nama pengguna

@dev_Boston hanya satu pengecualian ... lakukan saja dengan nilai-nilai ini v1 = 1.0001 dan v2 = 1.1. itu memberi saya sama.
Sankar M

8
Ya, string versi bukan string desimal, dan menambahkan nol ke bagian nomor versi tidak relevan. Dengan kata lain, "00001" sama dengan "1" di bagian ke-2 dari string versi.
JohnD

8
Anda dapat membandingkan lebih mudah dibaca Version.Parse(v1) < Version.Parse(v2), karena operator >(Version v1, Version v2)diterapkan.
Andrey Moiseev

Ketahuilah bahwa Version.Parse ("6.0.0") kurang dari (<) Version.Parse ("6.0.0.0") (yaitu TIDAK sama). Debug.Assert(new Version("6.0.0") < new Version("6.0.0.0"));
adospace

13

Jika Anda dapat hidup dengan skema major.minor.build.revision Anda bisa menggunakan kelas Versi .Net . Kalau tidak, Anda harus menerapkan semacam parsing dari kiri ke kanan dan melanjutkan sampai Anda memiliki perbedaan atau kembali bahwa dua versi sama.


7

Selain jawaban @JohnD mungkin ada kebutuhan untuk membandingkan hanya nomor versi parsial tanpa menggunakan Split ('.') Atau string lain <-> gembung konversi int. Saya baru saja menulis metode ekstensi CompareTo dengan 1 argumen tambahan - jumlah bagian signifikan dari nomor versi untuk membandingkan (antara 1 dan 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
Berhati-hatilah karena ini akan mengembalikan nilai yang sama untukcompareVersion("1.3", "1.3.1")
Ozgur Ozcitak

1

Jika karena alasan tertentu Anda tidak diizinkan untuk menggunakan metode perbandingan Versi secara langsung (misalnya dalam skenario client-server), pendekatan lain adalah mengekstraksi angka panjang dari versi dan kemudian membandingkan angka satu sama lain. Namun, nomor tersebut harus memiliki format berikut: Dua digit untuk Major, Minor dan Revisi dan empat digit untuk Build.

Cara mengekstrak nomor versi:

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

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

Dan kemudian di tempat lain Anda bisa membandingkan:

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

Catatan: versi terinstal adalah nomor lama yang sebelumnya diekstraksi


Untuk memberikan semua angka 3 tempat, kodenya harus benar-benar: "version.Major * 1000000000L + version.Minor * 1000000L + version.Build * 1000L + version.Revision"
Stef Heyenrath

1
@StefHeyenrath Itu benar, jangan ragu untuk menyesuaikan kode di atas dengan kebutuhan Anda sendiri.
Fabian Bigler
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.