From 39cd77b8e9d88040cab7a3551ba74dd747f393f7 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 27 Dec 2025 10:53:10 -0800 Subject: [PATCH] fix: Correct bugs in multiple value enum option help text (#553) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes several issues introduced in f1a8455: 1. ReflectionHelper.IsEnumerableType - The implementation had bugs: - type.IsAssignableTo(typeof(IEnumerable<>)) doesn't work for open generics - type.GenericTypeArguments[1] was wrong (arrays have element at index 0) Rewrote to properly handle arrays and generic types. 2. DefaultHelpTextGenerator.ExtractNamesFromEnum - Used wrong variable name (wrappedType2 instead of wrappedEnumerableType). 3. ValueParserProvider.GetParserImpl - Added array type support so app.Option() works with MultipleValue options. 4. Test expectation - Fixed expected help text format for MultipleValue options (--enumOpt5 not --enumOpt5[:]). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../Abstractions/ValueParserProvider.cs | 10 ++++++++++ .../HelpText/DefaultHelpTextGenerator.cs | 2 +- .../Internal/ReflectionHelper.cs | 17 +++++++++++++---- .../DefaultHelpTextGeneratorTests.cs | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/CommandLineUtils/Abstractions/ValueParserProvider.cs b/src/CommandLineUtils/Abstractions/ValueParserProvider.cs index d7b694df..89d730a7 100644 --- a/src/CommandLineUtils/Abstractions/ValueParserProvider.cs +++ b/src/CommandLineUtils/Abstractions/ValueParserProvider.cs @@ -133,6 +133,16 @@ public IValueParser GetParser(Type type) #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. } + // For array and collection types, return a parser for the element type + if (type.IsArray) + { + var elementType = type.GetElementType(); + if (elementType != null) + { + return GetParser(elementType); + } + } + return null; } diff --git a/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs b/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs index c64381b3..75aa0088 100644 --- a/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs +++ b/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs @@ -428,7 +428,7 @@ private string[] ExtractNamesFromEnum(Type? type) if (ReflectionHelper.IsEnumerableType(type, out var wrappedEnumerableType)) { - return ExtractNamesFromEnum(wrappedType2); + return ExtractNamesFromEnum(wrappedEnumerableType); } if (type.IsEnum) diff --git a/src/CommandLineUtils/Internal/ReflectionHelper.cs b/src/CommandLineUtils/Internal/ReflectionHelper.cs index e022390a..4d7e1c65 100644 --- a/src/CommandLineUtils/Internal/ReflectionHelper.cs +++ b/src/CommandLineUtils/Internal/ReflectionHelper.cs @@ -160,11 +160,20 @@ public static bool IsSpecialTupleType(Type type, [NotNullWhen(true)] out Type? w public static bool IsEnumerableType(Type type, [NotNullWhen(true)] out Type? wrappedType) { - var result = type.IsGenericType && - type.IsAssignableTo(typeof(IEnumerable<>)); - wrappedType = result ? type.GenericTypeArguments[1] : null; + if (type.IsArray) + { + wrappedType = type.GetElementType()!; + return true; + } - return result; + if (type.IsGenericType) + { + wrappedType = type.GenericTypeArguments[0]; + return true; + } + + wrappedType = null; + return false; } private static IEnumerable GetAllMembers(Type type) diff --git a/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs b/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs index 2f49639b..7f46adf4 100644 --- a/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs +++ b/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs @@ -165,7 +165,7 @@ SomeNullableEnumArgument nullable enum arg desc. Allowed values are: None, Normal, Extreme. --enumOpt4[:] nullable enum option desc. Allowed values are: None, Normal, Extreme. - --enumOpt5[:] multiple enum option desc. + --enumOpt5 multiple enum option desc. Allowed values are: None, Normal, Extreme. ",