Repository navigation
[API Proposal]: Type.GetEnumValuesAsUnderlyingType #72498
Description
Background and motivation
The existing Type.GetEnumValues API returns a System.Array that is of the given enum type (i.e. SomeEnum[] when called on typeof(SomeEnum)). This makes implementing the API challenging when the enum array cannot be created. There are multiple reasons why the enum array might not be possible to create:
- We're in a reflection-only context such as
MetadataLoadContext:Line 289 in d6e8686
public sealed override Array GetEnumValues() => throw new InvalidOperationException(SR.Arg_InvalidOperation_Reflection); - We're on a platform where runtime codegen (or universal shared code) is not available.
It would be good to have API that can work in these contexts by returning an array of the underlying type (i.e. int[] for typeof(SomeInt32Enum).
API Proposal
namespace System;
public abstract class Type
{
public virtual Array GetEnumValuesAsUnderlyingType();
}API Usage
foreach (var value in typeof(SomeEnum).GetEnumValuesAsUnderlyingType())
Console.WriteLine(value);
// Prints:
// 0
// 1
//
// As opposed to:
//
// SomeEnumValue1
// SomeEnumValue2Alternative Designs
Allow implementers to not satisfy the contract
The implementation of the existing Type.GetEnumValues could just return the underlying array directly since the signature is just System.Array. But that is probably pretty breaking - see #72236 (comment) for samples.
Write more code
Can be expressed in a less performant and more verbose way already:
foreach (var f in typeof(DayOfWeek).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
{
Console.WriteLine(f.Name);
Console.WriteLine(f.GetRawConstantValue()); // This returns the field value as boxed underlying type
}
Risks
No response
Activity
MichalPetryka commentedon Jul 20, 2022
Would this API return an array of the underlying type in all cases or only when it's not possible to figure out the type under AOT?
MichalStrehovsky commentedon Jul 20, 2022
In all cases. Switching the array type around would be a compat problem in the same sense as returning
int[]from the existing API. No reason to introduce it.MichalPetryka commentedon Jul 20, 2022
Does it make more sense to have the API on Type or in Enum? Currently APIs are in both of those places.
MichalStrehovsky commentedon Jul 20, 2022
For the
MetadataLoadContextuse case, theTypeAPI is the one that makes sense.I'll leave it up to the API review board whether it makes sense to add a shortcut on
Enumfor discoverability.GrabYourPitchforks commentedon Jul 20, 2022
@MichalStrehovsky This is marked blocking. Be sure to add a milestone (7.0 or Future) as well. Thanks!
MichalStrehovsky commentedon Jul 20, 2022
Marked for 7.0, thanks for spotting!
marek-safar commentedon Jul 22, 2022
/cc @lambdageek
terrajobst commentedon Jul 26, 2022
Video
Enumas this would maintain the parity with the existing methods that exist on bothTypeandEnum.