So sánh số phiên bản mà không sử dụng chức năng phân chia


124

Làm cách nào để so sánh số phiên bản?

Ví dụ:

x = 1.23.56.1487.5

y = 1.24.55.487.2


4
Bạn muốn kết quả là gì?
BoltClock

4
một phiên bản có 5 phần? Nếu bạn đang sử dụng phiên bản 4 phần thông thường, bạn có thể sử dụng lớp System.Version, bao gồm các phương thức để so sánh các phiên bản và phân tích chuỗi phiên bản
psousa

1
Các loại x và y là gì?
Gleno

5
Bất cứ khi nào ai đó nói "Đừng sử dụng X, Yhoặc Z", nó luôn khiến tôi tự hỏi tại sao. Tại sao bạn không muốn sử dụng splitchức năng? Các splitchức năng có vẻ như là một cách tốt để làm điều này nếu bạn đang không sử dụng các System.Versionlớp.
Bob2Chiv

Câu trả lời:


294

Bạn có thể sử dụng lớp Phiên bản không?

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

Nó có giao diện IComparable. Xin lưu ý rằng điều này sẽ không hoạt động với chuỗi phiên bản 5 phần như bạn đã hiển thị (đó có thực sự là chuỗi phiên bản của bạn không?). Giả sử đầu vào của bạn là các chuỗi, đây là một mẫu hoạt động với chuỗi phiên bản 4 phần .NET bình thường:

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
Chỉ khi phiên bản bao gồm từ 2-4 phần
tên người dùng

@dev_Boston chỉ có một ngoại lệ ... chỉ cần thực hiện với các giá trị này v1 = 1.0001 và v2 = 1.1 .it cho tôi bằng nhau.
Sankar M

8
Có, chuỗi phiên bản không phải là chuỗi thập phân và việc thêm các số 0 vào một phần của số phiên bản là không liên quan. Nói cách khác, "00001" bằng "1" trong phần 2 của chuỗi phiên bản.
JohnD

8
Bạn có thể so sánh dễ đọc hơn Version.Parse(v1) < Version.Parse(v2), bởi vì operator >(Version v1, Version v2)được thực hiện.
Andrey Moiseev

Xin lưu ý rằng Version.Pude ("6.0.0") nhỏ hơn (<) Version.Pude ("6.0.0.0") (tức là KHÔNG bằng nhau). Debug.Assert(new Version("6.0.0") < new Version("6.0.0.0"));
adospace

13

Nếu bạn có thể sống với lược đồ Major.minor.build.revision, bạn có thể sử dụng lớp .Net Version . Nếu không, bạn phải thực hiện một số loại phân tích cú pháp từ trái sang phải và tiếp tục cho đến khi bạn có sự khác biệt hoặc trả lại rằng hai phiên bản bằng nhau.


7

Ngoài câu trả lời của @JohnD, có thể chỉ cần so sánh các số phiên bản một phần mà không sử dụng Split ('.') Hoặc chuỗi khác <-> int bloat chuyển đổi. Tôi vừa mới viết một phương thức mở rộng So sánh với 1 đối số bổ sung - số phần quan trọng của số phiên bản để so sánh (giữa 1 và 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
Coi chừng rằng điều này sẽ trả lại bằng vớicompareVersion("1.3", "1.3.1")
Ozgur Ozcitak

1

Nếu vì một lý do nào đó, bạn không được phép sử dụng trực tiếp phương thức so sánh của Phiên bản (ví dụ: trong kịch bản máy khách-máy chủ), một cách tiếp cận khác là trích xuất một số dài từ phiên bản và sau đó so sánh các số với nhau. Tuy nhiên, số cần phải có định dạng sau: Hai chữ số cho Chính, Nhỏ và Sửa đổi và bốn cho Xây dựng.

Cách trích xuất số phiên bản:

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

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

Và sau đó ở một nơi khác bạn chỉ có thể so sánh:

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

Lưu ý: installVersion là một số dài được trích xuất trước đó


Để cung cấp cho tất cả các chữ số 3 vị trí, mã thực sự phải là: "phiên bản.Major * 1000000000L + phiên bản. Phiên bản * 1000000L + phiên bản.Build * 1000L + phiên bản.
Sửa đổi

1
@StefHeyenrath Điều đó là chính xác, hãy thoải mái điều chỉnh mã trên theo nhu cầu của riêng bạn.
Fabian Bigler
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.