比较版本返回太长或太短异常

Posted

技术标签:

【中文标题】比较版本返回太长或太短异常【英文标题】: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);

抛出异常

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

我该如何解决?

【问题讨论】:

【参考方案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位数)

以上是关于比较版本返回太长或太短异常的主要内容,如果未能解决你的问题,请参考以下文章

无法移动、剪切、复制文件 出现指定的文件名无效或太长

指定的文件名无效或太长,请指定另一个文件名

软件构造第四章第一节 面向可理解性的构造

C#/C++ - 如何获取路径太长或权限被拒绝的目录大小?

plsql很好用的自定义设置转载

会话 id 太长或包含非法字符,有效字符为 a-z、A-Z、0-9 和 '-,'