Covariance generic arguments don't work with Enums? #9342
-
I'm confused about Enums and why they seem to fail with covariance generic arguments. Everything I can see tells me that all enums inherit from the base Enum class. However, I cannot assign Why not? public class Person { }
public class Employee : Person { }
public enum EnumNumbers
{
One
}
public static void Test()
{
// IEnumerable<out T> supports covariance
IEnumerable<Employee> employees = new List<Employee>();
IEnumerable<Person> people = employees; // Covariance works
IEnumerable<EnumNumbers> numbers = new List<EnumNumbers>();
IEnumerable<Enum> enums = numbers; // ERROR: Covariance not working?
// EnumNumbers does indeed inherit from Enum
Enum value = EnumNumbers.One;
// Always true
if (EnumNumbers.One is Enum)
{
}
// The generic constraint agrees, IEnumerable<EnumNumbers> is covariant of IEnumerable<Enum>
GenericConstraintTest(numbers);
}
public static void GenericConstraintTest<T>(IEnumerable<T> value)
where T : Enum
{
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Generic variance doesn't work with value types. While |
Beta Was this translation helpful? Give feedback.
-
You could probably achieve this with wrappers: abstract class EnumWrapperBase
{
public abstract Enum ValueTypeless { get; }
}
class EnumWrapper<T>(T value) : EnumWrapperBase
where T : Enum, struct
{
public T Value { get; } = value;
public override Enum ValueTypeless => this.Value;
}
IEnumerable<EnumWrapper<MyEnum>> x = ...;
IEnumerable<EnumWrapperBase> y = x; // should work However, this entails allocating an object for each enum value, so I'm not sure how useful this is. |
Beta Was this translation helpful? Give feedback.
Generic variance doesn't work with value types. While
System.Enum
itself is technically a reference type, every implementation of an enum is a value type and has the same layout as the underlying integral type.