【问题标题】:comparing version return too long or too short exception比较版本返回太长或太短异常
【发布时间】:2019-08-27 03:07:32
【问题描述】:

这是我比较版本的方式

var _vA = new Version("0.9.9.1.1");
var _vB = new Version("0.9.9.1.2");

return (_vA.CompareTo(_vB) <= 0);

抛出异常

版本字符串部分太短或太长。

我该如何解决?

【问题讨论】:

    标签: c# version


    【解决方案1】:

    如果保证两个版本都是格式

    A.B.C ... .X.Y.Z
    

    所有版本的部分(AB、...、Z)只能包含 数字 0..9(我们可以在 的帮助下检查正则表达式 - bool isValid = Regex.IsMatch(version, @"^[0-9]+(\.[0-9]+)*$");),我们可以将它们比较为

    private static string[] VersionToArray(string version) {
      string[] result = version
        .Split('.')
        .Select(item => item.TrimStart('0'))
        .ToArray();
    
      // If we want to remove trailing zeros, i.e. 1.0.0.0.0.0 == 1.0.0.0 == 1.0:
      result = result
        .Reverse()
        .SkipWhile(item => item.All(c => c == '0'))
        .Reverse()
        .ToArray();
    
      return result;
    }
    
    private static int CompareVersions(string left, string right) {
      string[] leftArray = VersionToArray(left);
      string[] rightArray = VersionToArray(right);
    
      for (int i = 0; i < Math.Min(leftArray.Length, rightArray.Length); ++i) {
        int result = leftArray[i].Length.CompareTo(rightArray[i].Length);
    
        if (result == 0)
          result = string.Compare(leftArray[i], rightArray[i]);
    
        if (result != 0)
          return result;
      }
    
      return leftArray.Length.CompareTo(rightArray.Length);
    }
    

    演示:

    Tuple<string, string>[] tests = new Tuple<string, string>[] {
      Tuple.Create("0.9.9.1.2", "0.9.9.1.1"),
      Tuple.Create("0.9.9.1.1", "0.9.9.1.2"),
      Tuple.Create("0.9.9.1.1", "0.9.9.1.1"),
      Tuple.Create("0", "1"),
      Tuple.Create("0", "0.0.0.0"),
      Tuple.Create("0.0.1.0", "0.0.0.1"),
      Tuple.Create("1.0", "1.0.0"),
      Tuple.Create("1.10", "1.1"),
      Tuple.Create("1.1", "1.01"),
      Tuple.Create("10.0", "9.0"),
      Tuple.Create("012345678901234567890.1", "012345678901234567890.1"),
    };
    
    string demo = string.Join(Environment.NewLine, tests
      .Select(test => new {
         v1 = test.Item1,
         v2 = test.Item2,
         comp = CompareVersions(test.Item1, test.Item2)
       })
       .Select(rec => 
          $"{rec.v1,25} {(rec.comp == 0 ? "=" : rec.comp < 0 ? "<" : ">")} {rec.v2}"));
    
    Console.Write(demo);
    

    结果:

                    0.9.9.1.2 > 0.9.9.1.1
                    0.9.9.1.1 < 0.9.9.1.2
                    0.9.9.1.1 = 0.9.9.1.1
                            0 < 1
                            0 = 0.0.0.0
                      0.0.1.0 > 0.0.0.1
                          1.0 = 1.0.0
                         1.10 > 1.1
                          1.1 = 1.01
                         10.0 > 9.0
      012345678901234567890.1 = 012345678901234567890.1
    

    编辑:如果我们想返回bool,如果source &gt;= target(即source至少target),请参阅下面的cmets,我们可以放

      string source = "1.2.3.0.4.5.7";  // actual version
      string target = "1.2.3.0.3.9.75"; // minimum accepted version
    
      if (CompareVersions(source, target) >= 0) {
        // source is at least target, i.e. source >= target
      }
    

    【讨论】:

    • 假设left 是目标,right 是源。我只想重新运行Boolean 值,该值可以通过比较目标来判断源是否是最新的。
    • @Steven Sann:if (CompareVersions(source, target) &gt;= 0) {/* source &gt;= target */},请看我的编辑。
    【解决方案2】:

    该版本通常允许 2 到 4 个组件。在您的示例中,您有更多组件。要解决此问题,您需要删除版本的组件。例如,

    0.9.9.1
    0.9.9.2
    

    您可以阅读更多关于版本here

    典型的版本组件是

    Major:具有相同名称但不同主要版本的程序集是 不可互换。较高的版本号可能表示主要 在无法假定向后兼容的情况下重写产品。

    次要:如果两个程序集上的名称和主要版本号是 相同,但次要版本号不同,这表示 为了向后兼容而显着增强。 这个较高的次要版本号可能表示一个点版本 产品或完全向后兼容的新产品版本。

    构建:内部版本号的差异表示重新编译 相同的来源。处理器时可能会使用不同的内部版本号, 平台或编译器更改。

    修订:具有相同名称、主要和次要版本的程序集 数字,但不同的修订旨在完全 可互换。可能会在构建中使用更高的修订号 修复了先前发布的程序集中的安全漏洞。

    【讨论】:

    • 有什么方法可以比较这么长的版本字符串吗? (5位数)
    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    相关资源
    最近更新 更多