A command method parameter typed as an enum, with a default value pointing at a non-zero-valued enum member, fails to compile. The generator emits the member's underlying integer value as a bare int literal instead of a cast or the qualified member reference, and C# only allows implicit int-to-enum conversion for the literal 0.
Repro
Nullean.Argh 0.18.0, .NET SDK 10.0.300.
using Nullean.Argh;
var app = new ArghApp();
app.Map<Commands>();
return await app.RunAsync(args);
public enum ZeroBased { None = 0, A = 1 }
public enum OneBased { None = 1, A = 2 }
public sealed class Commands
{
/// <param name="level">-l, --level, level.</param>
[CommandName("zero")]
public int Zero(ZeroBased level = ZeroBased.None) => (int)level;
/// <param name="level">-l, --level, level.</param>
[CommandName("one")]
public int One(OneBased level = OneBased.None) => (int)level;
}
zero builds and runs fine. one — identical shape, the only difference is None = 1 instead of None = 0 — fails:
obj/.../ArghGenerated.g.cs(733,39): error CS0266: Cannot implicitly convert type 'int' to 'OneBased'. An explicit conversion exists (are you missing a cast?)
obj/.../ArghGenerated.g.cs(882,13): error CS0266: Cannot implicitly convert type 'int' to 'OneBased'. An explicit conversion exists (are you missing a cast?)
Looking at the generated source, the default-value local is initialized with the bare underlying value instead of a cast:
OneBased level = 1; // should be: (OneBased)1, or OneBased.None
This will hit anyone with an existing enum whose first/default member isn't 0 — a fairly common pattern for "not-yet-parsed"/sentinel-avoidance reasons, or just historical numbering (I hit this trying to reuse enum SuggestedVersionChange { None = 1, Patch = 2, Minor = 3, Major = 4 } as a CLI option type).
Expected
Enum parameters work regardless of which member is 0 — the generator should emit a cast (or the qualified member name) for the default-value initializer instead of a bare integer literal.
A command method parameter typed as an enum, with a default value pointing at a non-zero-valued enum member, fails to compile. The generator emits the member's underlying integer value as a bare
intliteral instead of a cast or the qualified member reference, and C# only allows implicitint-to-enum conversion for the literal0.Repro
Nullean.Argh0.18.0, .NET SDK 10.0.300.zerobuilds and runs fine.one— identical shape, the only difference isNone = 1instead ofNone = 0— fails:Looking at the generated source, the default-value local is initialized with the bare underlying value instead of a cast:
This will hit anyone with an existing enum whose first/default member isn't
0— a fairly common pattern for "not-yet-parsed"/sentinel-avoidance reasons, or just historical numbering (I hit this trying to reuseenum SuggestedVersionChange { None = 1, Patch = 2, Minor = 3, Major = 4 }as a CLI option type).Expected
Enum parameters work regardless of which member is
0— the generator should emit a cast (or the qualified member name) for the default-value initializer instead of a bare integer literal.