Possible Duplicates:
Anyone know a good workaround for the lack of an enum generic constraint?
Create Generic method constraining T to an Enum
Is is possible to limit the generic type parameter [I don't know if that's the right name] to an Enum
?
For example how do I do something like this?
//VB.NET
Function GetValues(Of T As System.Enum)(ByVal value As T) As IEnumerable(Of T)
Return [Enum].GetValues(value.GetType)
End Function
//C#
public IEnumerable<T> GetValues<T>(T value) where T : System.Enum
{
return Enum.GetValues(value.GetType());
}
Update
I eventually used Jon Skeet's Unconstrained Melody for that purpose. Thanks to you all for your contributions.
Unfortunately, you cannot - Microsoft closed this one out as a won't fix item.
You can treat enums as structs and use that as the constraint instead (I think that was how Jon Skeet did it in Unconstrained Melody?) but that is kind of unsightly.
You can't. An alternative solution is using struct
and run-time check.
public IEnumerable<T> GetValues<T>(T value) where T : struct
{
if (!typeof(T).IsEnum) throw new NotSupportedException();
return (IEnumerable<T>)Enum.GetValues(value.GetType());
}
Enum.GetValues
returns an Array
(whose elements are just Objects), which does not cast implicitly to an IEnumerable<T>
. - KeithS
Matt's and Danny's answers both have half the answer. This should actually get you what you need:
public IEnumerable<T> GetValues<T>() where T : struct
{
if (!typeof(T).IsEnum) throw new InvalidOperationException("Generic type argument is not a System.Enum");
return Enum.GetValues(typeof(T)).OfType<T>();
}
Changes from Danny's answer:
return Enum.GetValues(typeof(T)).Cast<T>()
- Metro Smurf
There is no need to make your method generic in this way.
You can just use the System.Enum
as the type parameter in your return type:
using System.Linq;
.
.
.
public IEnumerable<Enum> GetValues(Enum value)
{
return Enum.GetValues(value.GetType()).OfType<Enum>();
}
Array
isn't generic). - Matt Ellen