-1

I am currently receiving the following error - "Version string portion was too short or too long"

When using this statement -

records = records.OrderBy(r => new Version(r.RefNo)).ToList();

To order a list of string's called RefNo. It fails on 25.1.2.1.2 so i assume it is because it has four decimal points? as it works ok with 3....

Is the max four deciaml points for system.version?

Thanks

bsod_
  • 903
  • 8
  • 27
  • 1
    https://msdn.microsoft.com/en-us/library/system.version(v=vs.110).aspx#Anchor_6 `Is the max four deciaml points for system.version?` Yes. – mjwills Mar 15 '18 at 12:25
  • https://msdn.microsoft.com/en-us/library/y0hf9t2e(v=vs.110).aspx - have a look at remarks `The version parameter can contain only the components major, minor, build, and revision, in that order, and all separated by periods.` – Rand Random Mar 15 '18 at 12:26
  • Those aren't decimal points. A decimal point is a `.` character (typically called "full stop" or "period") placed in a set of digits to separate the integral portion of a number from the fractional portion. (In some other contexts, the decimal point may be the comma, `,`). Notably, it *does not make sense* for any number to contain more than a single decimal point. – Damien_The_Unbeliever Mar 15 '18 at 12:36
  • And the reason I try to make people get very clear on this is to make people realise that version `3.20` is different to version `3.2`, and is a later version than `3.9`. It's people who act as if it *is* a decimal separator (and somehow create a rule where you ignore the subsequent `.`s) who end up not understanding version numbering. – Damien_The_Unbeliever Mar 15 '18 at 12:44

3 Answers3

3

A Version can only have 4 parts:

major, minor, build, and revision, in that order, and all separated by periods.

That's why your approach fails. You could create an extension-method which handles this case, f.e.:

public static Version TryParseVersion(this string versionString)
{
    if (string.IsNullOrEmpty(versionString))
        return null;

    String[] tokens = versionString.Split('.');
    if (tokens.Length < 2 || !tokens.All(t => t.All(char.IsDigit)))
        return null;

    if (tokens.Length > 4)
    {
        int maxVersionLength = tokens.Skip(4).Max(t => t.Length);
        string normalizedRest = string.Concat(tokens.Skip(4).Select(t => t.PadLeft(maxVersionLength, '0')));
        tokens[3] = $"{tokens[3].PadLeft(maxVersionLength, '0')}{normalizedRest}";
        Array.Resize(ref tokens, 4);
    }

    versionString = string.Join(".", tokens);
    bool valid = Version.TryParse(versionString, out Version v);
    return valid ? v : null;
}

Now you can use it in this way:

records = records
   .OrderBy(r => r.RefNo.TryParseVersion())
   .ToList();

With your sample this new version string will be parsed(successfully): 25.1.2.12

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

See MSDN

Costructor public Version(string version)

A string containing the major, minor, build, and revision numbers, where each number is delimited with a period character ('.').

Makes a total of 4 numbers.

Means the string is limited to 4 numbers, 5 lead to an error.

Also the costructors with int's as parameters only support 1 to 4 parameters.

Chrᴉz remembers Monica
  • 1,829
  • 1
  • 10
  • 24
0

sorry for the late reply but here is the finished extension method i used with a couple of alterations -

public static Version ParseRefNo(this string refNoString)
        {
            if (string.IsNullOrEmpty(refNoString))
                return null;

            String[] tokens = refNoString.Split('.');
            if (tokens.Length < 2 || !tokens.All(t => t.All(char.IsDigit)))
                return null;

            if (tokens.Length > 4)
            {
                int maxVersionLength = tokens.Skip(4).Max(t => t.Length);
                string normalizedRest = string.Concat(tokens.Skip(4).Select(t => t.PadLeft(maxVersionLength, '0')));
                tokens[3] = $"{tokens[3].PadLeft(maxVersionLength, '0')}{normalizedRest}";
                Array.Resize(ref tokens, 4);
            }

            refNoString = string.Join(".", tokens);
            Version v = null;
            bool valid = Version.TryParse(refNoString, out v);
            return valid ? v : null;
        }
bsod_
  • 903
  • 8
  • 27