commandlineparser / commandlineparser/commandline

Construction of immutable options objects fail in certain cultures

Offen
#804 0 Kommentare 4 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
C#
Sterne
4.8k
Forks
478
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

This is the same issue mentioned by brian-reichle in #188.

Given the following .NET 6 application:

```csharp
using CommandLine;
using System.Globalization;

if (args.Length == 0)
{
Console.Error.WriteLine("Missing command line argument parameter for culture code.");
return -1;
}

var culture = CultureInfo.GetCultureInfoByIetfLanguageTag(args[0]);
Thread.CurrentThread.CurrentCulture = culture;

Console.WriteLine($"Using culture {culture.IetfLanguageTag}");

return Parser.Default.ParseArguments(args.Skip(1))
.MapResult(
o =>
{
Console.WriteLine($"The integer is {o.Integer}");
return 0;
},
err => -2);

class MyOptions
{
public MyOptions(int integer)
{
Integer = integer;
}

[Option('i')]
public int Integer { get; }
}
```

Running this with en-US works as expected, whilst running it with tr-TR crashes:

With no arguments:
```plain
PS C:\Data\Temp\cliargs-cultured\ConsoleApp1\ConsoleApp1\bin\Debug\net6.0> .\ConsoleApp1.exe
Missing command line argument parameter for culture code.
```

In US English:
```plain
PS C:\Data\Temp\cliargs-cultured\ConsoleApp1\ConsoleApp1\bin\Debug\net6.0> .\ConsoleApp1.exe en-US
Using culture en-US
The integer is 0
```

In Turkish:
```plain
PS C:\Data\Temp\cliargs-cultured\ConsoleApp1\ConsoleApp1\bin\Debug\net6.0> .\ConsoleApp1.exe tr-TR
Using culture tr-TR
Unhandled exception. System.InvalidOperationException: Type MyOptions appears to be Immutable with invalid constructor. Check that constructor arguments have the same name and order of their underlying Type. Constructor Parameters can be ordered as: '(integer)'
at CommandLine.Core.InstanceBuilder.BuildImmutable[T](Type typeInfo, Maybe`1 factory, IEnumerable`1 specProps, IEnumerable`1 specPropsWithValue, List`1 setPropertyErrors)
at CommandLine.Core.InstanceBuilder.<>c__DisplayClass0_0`1.b__5()
at CommandLine.Core.InstanceBuilder.Build[T](Maybe`1 factory, Func`3 tokenizer, IEnumerable`1 arguments, StringComparer nameComparer, Boolean ignoreValueCase, CultureInfo parsingCulture, Boolean autoHelp, Boolean autoVersion, IEnumerable`1 nonFatalErrors)
at CommandLine.Parser.ParseArguments[T](IEnumerable`1 args)
at Program.$(String[] args) in C:\Data\Temp\cliargs-cultured\ConsoleApp1\ConsoleApp1\Program.cs:line 15
PS C:\Data\Temp\cliargs-cultured\ConsoleApp1\ConsoleApp1\bin\Debug\net6.0>
```

Interestingly the error message from the Turkish case says that my constructor parameters should be ordered as `(integer)`, which clearly it already is.

I believe this is due to the lowercasing to the leading capital I in the options object's properties.

With tr-TR, `I` does not get lowercased to `i` as one might expect, but it gets lowercased to `ı`.

I believe this is due to [the use of `ToLower()` here](https://github.com/commandlineparser/commandline/blob/d443a51aeb3a418425e970542b3b96e9da5f62e2/src/CommandLine/Core/InstanceBuilder.cs#L176), rather than `ToLowerInvariant()` as seen elsewhere in the file.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.