Get Constituent Values of a Combined Enumerated Value
The following code was inspired and co-written by FourBlades.
The following method will take any combined enumerated value and return an array containing the constituent parts. It is intended to be used with enumerated types that have the Flags attribute applied, allowing you to combine multiple values into a single value, where each bit of the composite value represents one of the flags. An example of such a type is the FontStyle enumeration.
VB.NET Code:
Public Function GetConstituentFlags(Of T)(ByVal value As T) As T()
Dim genericType As Type = GetType(T)
If Not genericType.IsEnum Then
Throw New ArgumentException("Generic argument type must be an enumerated type.")
End If
Dim numericValue As Integer = Convert.ToInt32(value)
Dim flags As New List(Of T)
If numericValue = 0 Then
If [Enum].IsDefined(genericType, 0) Then
flags.Add(DirectCast([Enum].ToObject(genericType, 0), T))
End If
Else
For Each constant As Integer In [Enum].GetValues(genericType)
If constant <> 0 AndAlso (numericValue And constant) = constant Then
flags.Add(DirectCast([Enum].ToObject(genericType, constant), T))
End If
Next constant
End If
Return flags.ToArray()
End Function
This is a good example of a generic function. Many people will only be familiar with generics in relation to collections. If you want to see it in action, try editing the Bold, Italic, Underline and Strikethrough properties of a form's Font property and running the project with this code:
VB.NET Code:
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
For Each style As FontStyle In Me.GetConstituentFlags(Me.Font.Style)
MessageBox.Show(style.ToString())
Next style
End Sub
Note that if you don't apply any styles to the font the method automatically returns the zero value for that enumeration, which is Regular. I haven't specifically tested it but this method should also support negative values.
Re: Get Constituent Values of a Combined Enumerated Value
The following method, a variation on the method in post#1, will take any combined or single enumerated value as an instance of any Enumeration and return an array containing the both the lowest and highest value found in the given Enum Type. It is intended to be used with enumerated types.
In this function, the following line of code uses GetValues to return An Array of the values of the constants in value (ByVal value As T).
Code:
Dim values() As Integer = CType([Enum].GetValues(genericType), Integer())
The elements of the return array are sorted by the values of the enumeration constants; therefore, sorting is not required to ensure that the subsequent lines of code correctly return the lowest & highest (in that order) enum values found in the Type represented by value (ByVal value As T).
The full Function is:
Code:
Public Shared Function GetLowAndHighEnumValues(Of T)(ByVal value As T) As T()
Dim genericType As Type = GetType(T)
If Not genericType.IsEnum Then
Throw New ArgumentException("Argument 'T' must be an enumerated type. " & genericType.FullName & " is not a valid parameter for function 'GetLowAndHighEnumValues' ")
End If
Dim flags As New List(Of T)
Dim values() As Integer = CType([Enum].GetValues(genericType), Integer())
flags.Add(DirectCast([Enum].ToObject(genericType, values(0)), T))
flags.Add(DirectCast([Enum].ToObject(genericType, values(values.GetUpperBound(0))), T))
Return flags.ToArray
End Function
An example of the usage of this function is:
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim styles() As FontStyle = GetLowAndHighEnumValues(FontStyle.Bold)
For Each style As FontStyle In styles
MessageBox.Show(style.ToString)
Next
End Sub