commandlineparser / commandlineparser/commandline

Construction of immutable options objects fail in certain cultures

未關閉
#804 0 則留言 4 個 reaction 已指派 0 人 在 GitHub 檢視
主要語言
C#
星號
4.8k
分支
478
PR 合併指標
30 天內沒有已合併 PR

描述

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.

貢獻指南

這個儲存庫沒有索引到貢獻指南

研究方向

The failure is in src/CommandLine/Core/InstanceBuilder.cs at the linked ToLower() call; start there and compare nearby invariant casing uses. Reproduce the supplied .NET 6 MyOptions example under en-US and tr-TR, then verify immutable construction succeeds in both cultures and the diagnostic remains correct.

由索引模型根據 Issue 內容生成。

評估

技術堆疊
csharp
領域
cli
Issue 類型
缺陷
難度
2/5
預估耗時
1-3 小時
活躍度
停滯
描述清晰度
描述清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。