I wrote this EnumHelper method
public static IEnumerable<T> AsEnumerable<TEnum, T>(Func<TEnum, T> projection = null) where TEnum : struct
{
if (!typeof(TEnum).IsEnum)
throw new InvalidOperationException("Type parameter TEnum must be an enum");
if (projection == null)
return Enum.GetValues(typeof (TEnum)).OfType<TEnum>();
return Enum.GetValues(typeof (TEnum)).OfType<TEnum>().Select(projection);
}
I get a compile time error in the first return. That returns an IEnumerable<TEnum>
Error 46 Cannot implicitly convert type System.Collections.Generic.IEnumerable<TEnum> to System.Collections.Generic.IEnumerable<T>
I don’t have any constraints on T, so T is more generic than TEnum. In IEnumerable<out T> T is convariant, so why do I still get the error?
Covariance only applies if there is a polymorphic relationship between the two types. In your case,
TEnumandTare not constrained to be related, so covariance does not apply.You could trivially fix this issue by casting your enumeration members directly to your target type:
Edit: I would suggest eliminating the
projectionparameter, and define your method more simply like so:If you do need to perform a projection, you could use the standard LINQ
Selectoperation on the returned sequence:This will give you practically the same conciseness as your code, but save you the trouble of maintaining the optional parameter.
Edit2: If you really want to define an overload for the projection, I would suggest implementing all the logic within it, and then call it using the identity function from the parameterless version:
Sample calls: