比较版本 return 太长或太短异常

comparing version return too long or too short exception

这是我比较版本

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

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

抛出异常

Version string portion was too short or too long.

我该如何解决?

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

0.9.9.1
0.9.9.2

您可以在版本 here

上阅读更多内容

典型的版本组件是

Major: Assemblies with the same name but different major versions are not interchangeable. A higher version number might indicate a major rewrite of a product where backward compatibility cannot be assumed.

Minor: If the name and major version number on two assemblies are the same, but the minor version number is different, this indicates significant enhancement with the intention of backward compatibility. This higher minor version number might indicate a point release of a product or a fully backward-compatible new version of a product.

Build: A difference in build number represents a recompilation of the same source. Different build numbers might be used when the processor, platform, or compiler changes.

Revision: Assemblies with the same name, major, and minor version numbers but different revisions are intended to be fully interchangeable. A higher revision number might be used in a build that fixes a security hole in a previously released assembly.

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

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

编辑: 如果我们想要 return bool 如果 source >= target(即 source至少 target),看下面的评论,我们可以把

  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
  }