neelbak
asked on
What is the best way to combine an enum with a string value
Below are 2 functions that I have associated with an enum and it's value. What is the best way to combine these items into one object type to give me the following functionality. I basically want to be able to pass an enum value as parameters but parse and output the Textual description of the enum.
I'm open to suggestions on the best way to handle this. I have about 20 different enums and want to have each enum's functions contained.
' Looking for behavior similar to this
Dim x as GenderType ' No instantiation necessary
x = Gender.Male ' setting takes a enum value
x.ToString() ' to string returns a string value of the current enum
x.Parse("Male") ' sets x to Gender.Male
Public enum Gender
NotSpecified = 0
Male = 1
Female = 2
end enum
Public Function ToString_Gender(ByVal val as Gender) as String
select case val
case Gender.NotSpecified
return "Not Specified"
case Gender.Male
return "Male"
case Gender.Female"
return "Female"
case else
return String.empty
end select
end function
Public Function Parse_Gender(ByVal text as string) as Gender
select case "Not Specified"
return Gender.NotSpecified
select case "Male"
return Gender.Male
select case "Female"
return Gender.Female
case else
return nothing
end select
end function
I'm open to suggestions on the best way to handle this. I have about 20 different enums and want to have each enum's functions contained.
' Looking for behavior similar to this
Dim x as GenderType ' No instantiation necessary
x = Gender.Male ' setting takes a enum value
x.ToString() ' to string returns a string value of the current enum
x.Parse("Male") ' sets x to Gender.Male
Public enum Gender
NotSpecified = 0
Male = 1
Female = 2
end enum
Public Function ToString_Gender(ByVal val as Gender) as String
select case val
case Gender.NotSpecified
return "Not Specified"
case Gender.Male
return "Male"
case Gender.Female"
return "Female"
case else
return String.empty
end select
end function
Public Function Parse_Gender(ByVal text as string) as Gender
select case "Not Specified"
return Gender.NotSpecified
select case "Male"
return Gender.Male
select case "Female"
return Gender.Female
case else
return nothing
end select
end function
This bit of code will allow you to have the enum be different then it’s description. Also it keeps the description of the enum value right with the enum declaration, which in my book is a good idea.
Your enum: (this enum will work the same as a normal enum, notice you can type what ever for the description)
Public Enum Gender
<System.ComponentModel.Des cription(" Not Specified")> NotSpecified = 0
<System.ComponentModel.Des cription(" Male")> Male = 1
<System.ComponentModel.Des cription(" Female")> Female = 2
End Enum
The code: (don't some complex reflection I know, but I tested it)
Public Function EnumToDescription(ByVal Value As [Enum]) As String
'get the type of the enum
Dim type As System.Type = Value.GetType
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In type.GetMembers(Reflection .BindingFl ags.Public Or Reflection.BindingFlags.St atic)
If member.MemberType = Reflection.MemberTypes.Fie ld Then
'test to see if this field equals the given value
If System.Enum.ToObject(Value .GetType, Value).Equals(DirectCast(m ember, Reflection.FieldInfo).GetV alue(Nothi ng)) Then
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes (False)
If TypeOf att Is System.ComponentModel.Desc riptionAtt ribute Then
'we found the description, return it
Return DirectCast(att, System.ComponentModel.Desc riptionAtt ribute).De scription
End If
Next
End If
End If
Next
'after all this work we could not find anything that matches
Return ""
End Function
Public Function DescriptionToEnum(ByVal EnumType As Type, ByVal Description As String) As [Enum]
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In EnumType.GetMembers(Reflec tion.Bindi ngFlags.Pu blic Or Reflection.BindingFlags.St atic)
If member.MemberType = Reflection.MemberTypes.Fie ld Then
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes (False)
If TypeOf att Is System.ComponentModel.Desc riptionAtt ribute Then
'we found the description, compair it to what we were given
If DirectCast(att, System.ComponentModel.Desc riptionAtt ribute).De scription = Description Then
'we want to return this value
Return DirectCast(DirectCast(memb er, Reflection.FieldInfo).GetV alue(Nothi ng), [Enum])
End If
End If
Next
End If
Next
'could not find a description matching in this enum type
Return DirectCast(Nothing, [Enum])
End Function
The test drive: (try this out to see the above functions in action)
'the code below goes from enum value to that enums description then from a description back to the enum.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Des As String = EnumToDescription(Gender.N otSpecifie d)
Dim Gen As Gender = DirectCast(DescriptionToEn um(GetType (Gender), Des), Gender)
MsgBox(Des & vbCrLf & Gen.ToString & vbCrLf & CInt(System.Enum.ToObject( GetType(Ge nder), Gen)))
End Sub
One possible down side I see to this code is that you have to know what type of enum the description is from to parse from description to enum. Also there is a ton of directcasting, which may or may not suit you.
Your enum: (this enum will work the same as a normal enum, notice you can type what ever for the description)
Public Enum Gender
<System.ComponentModel.Des
<System.ComponentModel.Des
<System.ComponentModel.Des
End Enum
The code: (don't some complex reflection I know, but I tested it)
Public Function EnumToDescription(ByVal Value As [Enum]) As String
'get the type of the enum
Dim type As System.Type = Value.GetType
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In type.GetMembers(Reflection
If member.MemberType = Reflection.MemberTypes.Fie
'test to see if this field equals the given value
If System.Enum.ToObject(Value
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes
If TypeOf att Is System.ComponentModel.Desc
'we found the description, return it
Return DirectCast(att, System.ComponentModel.Desc
End If
Next
End If
End If
Next
'after all this work we could not find anything that matches
Return ""
End Function
Public Function DescriptionToEnum(ByVal EnumType As Type, ByVal Description As String) As [Enum]
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In EnumType.GetMembers(Reflec
If member.MemberType = Reflection.MemberTypes.Fie
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes
If TypeOf att Is System.ComponentModel.Desc
'we found the description, compair it to what we were given
If DirectCast(att, System.ComponentModel.Desc
'we want to return this value
Return DirectCast(DirectCast(memb
End If
End If
Next
End If
Next
'could not find a description matching in this enum type
Return DirectCast(Nothing, [Enum])
End Function
The test drive: (try this out to see the above functions in action)
'the code below goes from enum value to that enums description then from a description back to the enum.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Des As String = EnumToDescription(Gender.N
Dim Gen As Gender = DirectCast(DescriptionToEn
MsgBox(Des & vbCrLf & Gen.ToString & vbCrLf & CInt(System.Enum.ToObject(
End Sub
One possible down side I see to this code is that you have to know what type of enum the description is from to parse from description to enum. Also there is a ton of directcasting, which may or may not suit you.
Xersoft,
You are doing the 'exact' same thing I did with 3x as much code and complexity.
Simplify, don't over engineer!
MaitreMind
You are doing the 'exact' same thing I did with 3x as much code and complexity.
Simplify, don't over engineer!
MaitreMind
MaitreMind,
Did you notice his description for NotSpecified is 'Not Specified' with a space?
I was unable to get your code to allow this sort of description. Also what if I wanted to have a description for an enum value that was an entire sentence?
I may be wrong but I'm not seeing how your code allows a description of anything other then the enum value text.
I'm sorry if I'm missing something in your code.
Also I'm not sure if this is something neelbak needs or not...
Did you notice his description for NotSpecified is 'Not Specified' with a space?
I was unable to get your code to allow this sort of description. Also what if I wanted to have a description for an enum value that was an entire sentence?
I may be wrong but I'm not seeing how your code allows a description of anything other then the enum value text.
I'm sorry if I'm missing something in your code.
Also I'm not sure if this is something neelbak needs or not...
ASKER
xersoft is on the right track. I do need to separate out the description of the enum value to allow for full setences or spaces. MaitreMind, your example just gets me the name of the enum but doesn't allow for a complete description.
xersoft, your code works for doing this. The only thing is that I would like to encapsulate this into a object to have the same type of functionality as a base type such as "Integer".
For example
Dim y as integer
y = Integer.Parse("23")
y.ToString() 'Outputs 23
y = 23
So like I said in my orginal question. How do I get that functionality into my object type?
' Looking for behavior similar to this
Dim x as GenderType ' No instantiation necessary
x = Gender.Male ' setting takes a enum value
x.ToString() ' to string returns a string value of the current enum
x.Parse("Male") ' sets x to Gender.Male
x = GenderType.Parse("Male") ' or this for parsing
xersoft, your code works for doing this. The only thing is that I would like to encapsulate this into a object to have the same type of functionality as a base type such as "Integer".
For example
Dim y as integer
y = Integer.Parse("23")
y.ToString() 'Outputs 23
y = 23
So like I said in my orginal question. How do I get that functionality into my object type?
' Looking for behavior similar to this
Dim x as GenderType ' No instantiation necessary
x = Gender.Male ' setting takes a enum value
x.ToString() ' to string returns a string value of the current enum
x.Parse("Male") ' sets x to Gender.Male
x = GenderType.Parse("Male") ' or this for parsing
ASKER
This is starting to fustrate me so I'm raising the stakes with some extra points. :-)
Are you using VB2005 by chance? Or would you use c# for this?
You could override the = operator and get this functionality I think.
Pre 2005 VB won’t allow this though.
You could override the = operator and get this functionality I think.
Pre 2005 VB won’t allow this though.
ASKER
I'm using VB2005
Here is a class I came up with that I think might fit your need.
Public Class Gender
Private mvalue As Integer
Private Shared mNotSpecified As Gender = New Gender(0)
Private Shared mMale As Gender = New Gender(1)
Private Shared mFemale As Gender = New Gender(2)
<System.ComponentModel.Des cription(" Not Specified")> Public Shared ReadOnly Property NotSpecified() As Gender
Get
Return mNotSpecified
End Get
End Property
<System.ComponentModel.Des cription(" Male")> Public Shared ReadOnly Property Male() As Gender
Get
Return mMale
End Get
End Property
<System.ComponentModel.Des cription(" Female")> Public Shared ReadOnly Property Female() As Gender
Get
Return mFemale
End Get
End Property
#Region "Description"
Private Function GenderToDescription(ByVal Value As Integer) As String
'get the type of the enum
Dim type As System.Type = Me.GetType
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In type.GetMembers(Reflection .BindingFl ags.Public Or Reflection.BindingFlags.St atic)
If member.MemberType = Reflection.MemberTypes.Pro perty Then
'test to see if this field equals the given value
If DirectCast(DirectCast(memb er, Reflection.PropertyInfo).G etValue(No thing, Nothing), Gender).mvalue = Me.mvalue Then
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes (False)
If TypeOf att Is System.ComponentModel.Desc riptionAtt ribute Then
'we found the description, return it
Return DirectCast(att, System.ComponentModel.Desc riptionAtt ribute).De scription
End If
Next
End If
End If
Next
'after all this work we could not find anything that matches
Return ""
End Function
Private Shared Function DescriptionToGender(ByVal Description As String) As Gender
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In GetType(Gender).GetMembers (Reflectio n.BindingF lags.Publi c Or Reflection.BindingFlags.St atic)
If member.MemberType = Reflection.MemberTypes.Pro perty Then
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes (False)
If TypeOf att Is System.ComponentModel.Desc riptionAtt ribute Then
'we found the description, compair it to what we were given
If DirectCast(att, System.ComponentModel.Desc riptionAtt ribute).De scription = Description Then
'we want to return this value
Return DirectCast(DirectCast(memb er, Reflection.PropertyInfo).G etValue(No thing, Nothing), Gender)
End If
End If
Next
End If
Next
'could not find a description matching in this enum type
Return mNotSpecified
End Function
#End Region
Private Sub New(ByVal Value As Integer)
Me.mvalue = Value
End Sub
Public Sub New()
mvalue = 0
End Sub
Public Overrides Function ToString() As String
Return Me.GenderToDescription(mva lue)
End Function
Public Shared Function Parse(ByVal Description As String) As Gender
Return DescriptionToGender(Descri ption)
End Function
Public Shared Operator =(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue = g2.mvalue Then Return True Else Return False
End Operator
Public Shared Operator <>(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue <> g2.mvalue Then Return True Else Return False
End Operator
End Class
Public Class Gender
Private mvalue As Integer
Private Shared mNotSpecified As Gender = New Gender(0)
Private Shared mMale As Gender = New Gender(1)
Private Shared mFemale As Gender = New Gender(2)
<System.ComponentModel.Des
Get
Return mNotSpecified
End Get
End Property
<System.ComponentModel.Des
Get
Return mMale
End Get
End Property
<System.ComponentModel.Des
Get
Return mFemale
End Get
End Property
#Region "Description"
Private Function GenderToDescription(ByVal Value As Integer) As String
'get the type of the enum
Dim type As System.Type = Me.GetType
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In type.GetMembers(Reflection
If member.MemberType = Reflection.MemberTypes.Pro
'test to see if this field equals the given value
If DirectCast(DirectCast(memb
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes
If TypeOf att Is System.ComponentModel.Desc
'we found the description, return it
Return DirectCast(att, System.ComponentModel.Desc
End If
Next
End If
End If
Next
'after all this work we could not find anything that matches
Return ""
End Function
Private Shared Function DescriptionToGender(ByVal Description As String) As Gender
'iterate over all the members of this type
For Each member As Reflection.MemberInfo In GetType(Gender).GetMembers
If member.MemberType = Reflection.MemberTypes.Pro
'now look for the description attribute on this member
For Each att As Object In member.GetCustomAttributes
If TypeOf att Is System.ComponentModel.Desc
'we found the description, compair it to what we were given
If DirectCast(att, System.ComponentModel.Desc
'we want to return this value
Return DirectCast(DirectCast(memb
End If
End If
Next
End If
Next
'could not find a description matching in this enum type
Return mNotSpecified
End Function
#End Region
Private Sub New(ByVal Value As Integer)
Me.mvalue = Value
End Sub
Public Sub New()
mvalue = 0
End Sub
Public Overrides Function ToString() As String
Return Me.GenderToDescription(mva
End Function
Public Shared Function Parse(ByVal Description As String) As Gender
Return DescriptionToGender(Descri
End Function
Public Shared Operator =(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue = g2.mvalue Then Return True Else Return False
End Operator
Public Shared Operator <>(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue <> g2.mvalue Then Return True Else Return False
End Operator
End Class
I tested it with this, which I got from your post above:
Dim x As Gender
x = Gender.Male
x.ToString()
x = Gender.Parse("Male")
Dim y As Gender = Gender.Female
MsgBox(y = x)
x = y
MsgBox(x.ToString)
MsgBox(x = y)
Dim x As Gender
x = Gender.Male
x.ToString()
x = Gender.Parse("Male")
Dim y As Gender = Gender.Female
MsgBox(y = x)
x = y
MsgBox(x.ToString)
MsgBox(x = y)
Dim x as GenderType ' No instantiation necessary
x = Gender.Male ' setting takes a enum value
x.ToString() ' to string returns a string value of the current enum
x.Parse("Male") ' sets x to Gender.Male
x = GenderType.Parse("Male") ' or this for parsing
From your above list:
My idea requires instantiation i.e. Dim x as new GenderType
My idea does not allow the x.Parse(“Male”) to set x, you need to use x = Gender.Parse(“Male”)
Hope my ideas help.
x = Gender.Male ' setting takes a enum value
x.ToString() ' to string returns a string value of the current enum
x.Parse("Male") ' sets x to Gender.Male
x = GenderType.Parse("Male") ' or this for parsing
From your above list:
My idea requires instantiation i.e. Dim x as new GenderType
My idea does not allow the x.Parse(“Male”) to set x, you need to use x = Gender.Parse(“Male”)
Hope my ideas help.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
MaitreMind,
I’m all for keeping it simple but that just does not give him the functionality he needs, or at least that I understand he needs.
I’m understanding, neelbak, that you want to place this functionality into the enum itself?
Plus I imagine it would get pretty hard to describe an enum value with more then a few words.
I guess it all boils down to what is needed. If it’s worth creating complex code to get exactly what is needed, or is simpler code alright for your purposes.
I have to admit I see that appeal of placing the parse and tostring methods right in the enumeration.
Plus what if one wanted to offer other methods that deal specifically with that enum? One could add a method called GetMateType to the structure I provided and based on the current value value of the enum i.e. Male, Female a proper type could be returned. Now maybe that does not make much sense for this example but what about more complex examples?
Public enum FishTypes
FishA
FishB
FishC
FishD
FishE
FishF
End enum
Now say a method is needed to see all the types of fish one other specific type of fish eats.
Dim aFish as FishTypes = FishTypes.FishA
For each Fish as FishTypes in aFish.GetFoodTypes()
Msgbox Fish.ToString
Next
Define a GetFoodTypes method and return an array of FishTypes objects
Sure another possibly crazy example but hopefully you get the idea. Placing the GetFoodTypes method right in the enum makes sense and makes working with those enums more intuitive.
Sorry if I’m way off base here with these ideas.
I’m all for keeping it simple but that just does not give him the functionality he needs, or at least that I understand he needs.
I’m understanding, neelbak, that you want to place this functionality into the enum itself?
Plus I imagine it would get pretty hard to describe an enum value with more then a few words.
I guess it all boils down to what is needed. If it’s worth creating complex code to get exactly what is needed, or is simpler code alright for your purposes.
I have to admit I see that appeal of placing the parse and tostring methods right in the enumeration.
Plus what if one wanted to offer other methods that deal specifically with that enum? One could add a method called GetMateType to the structure I provided and based on the current value value of the enum i.e. Male, Female a proper type could be returned. Now maybe that does not make much sense for this example but what about more complex examples?
Public enum FishTypes
FishA
FishB
FishC
FishD
FishE
FishF
End enum
Now say a method is needed to see all the types of fish one other specific type of fish eats.
Dim aFish as FishTypes = FishTypes.FishA
For each Fish as FishTypes in aFish.GetFoodTypes()
Msgbox Fish.ToString
Next
Define a GetFoodTypes method and return an array of FishTypes objects
Sure another possibly crazy example but hopefully you get the idea. Placing the GetFoodTypes method right in the enum makes sense and makes working with those enums more intuitive.
Sorry if I’m way off base here with these ideas.
Here is a way to encapsulate it into your own structure
Note it would to be able to have a Default property so you could do this:
myGender = mygender.Not_Specified
VB.Net doesn't allow it:
Properties with no required parameters cannot be declared 'Default'.
Yet you can do this instead:
myGender.Set = myGender.Get.Not_Specified
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myGender As GenderStruct
Dim g1 As Gender
Dim sg1 As String
myGender.Set = Gender.Not_Specified
sg1 = myGender.ToString
g1 = myGender.Parse(sg1)
End Sub
Public Enum Gender
Not_Specified = 0
Male = 1
Female = 2
End Enum
'Note: All you would need to do in addition is add the any extra enum functionality GetType() etc. to the structure
Public Structure GenderStruct
Private _Gender As Gender
Public ReadOnly Property [Get]() As Gender
Get
Return _Gender
End Get
End Property
Public WriteOnly Property [Set]() As Gender
Set(ByVal Value As Gender)
_Gender = Value
End Set
End Property
Public Shadows Function ToString() As String
Return _Gender.ToString.Replace(" _", " ")
End Function
Public Function Parse(ByVal text As String) As Gender
Dim val As Gender
For Each val In [Enum].GetValues(_Gender.G etType)
If val.ToString.ToUpper = text.Replace(" ", "_").ToUpper Then
Return val
End If
Next
Return Nothing
End Function
End Structure
Keep it Simple ...
MaitreMind
Note it would to be able to have a Default property so you could do this:
myGender = mygender.Not_Specified
VB.Net doesn't allow it:
Properties with no required parameters cannot be declared 'Default'.
Yet you can do this instead:
myGender.Set = myGender.Get.Not_Specified
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myGender As GenderStruct
Dim g1 As Gender
Dim sg1 As String
myGender.Set = Gender.Not_Specified
sg1 = myGender.ToString
g1 = myGender.Parse(sg1)
End Sub
Public Enum Gender
Not_Specified = 0
Male = 1
Female = 2
End Enum
'Note: All you would need to do in addition is add the any extra enum functionality GetType() etc. to the structure
Public Structure GenderStruct
Private _Gender As Gender
Public ReadOnly Property [Get]() As Gender
Get
Return _Gender
End Get
End Property
Public WriteOnly Property [Set]() As Gender
Set(ByVal Value As Gender)
_Gender = Value
End Set
End Property
Public Shadows Function ToString() As String
Return _Gender.ToString.Replace("
End Function
Public Function Parse(ByVal text As String) As Gender
Dim val As Gender
For Each val In [Enum].GetValues(_Gender.G
If val.ToString.ToUpper = text.Replace(" ", "_").ToUpper Then
Return val
End If
Next
Return Nothing
End Function
End Structure
Keep it Simple ...
MaitreMind
I don't understand why
x.Set = Gender.Female
is simpler then
x = Gender.Femail
as my examples allow one to do?
Is it the amout of code that troubles you MaitreMind? It's not so much more code, no hundreds of lines longer...
x.Set = Gender.Female
is simpler then
x = Gender.Femail
as my examples allow one to do?
Is it the amout of code that troubles you MaitreMind? It's not so much more code, no hundreds of lines longer...
one benefit I see to your code MaitreMind:
Dim x As GenderStruct
x.set = [brings up a list of posable values]
in my example
dim x as Gender
x = Gender. [Brings up a list of possable values]
you have to type out that word Gender everytime. That might hurt more with longer named enums.
Dim x As GenderStruct
x.set = [brings up a list of posable values]
in my example
dim x as Gender
x = Gender. [Brings up a list of possable values]
you have to type out that word Gender everytime. That might hurt more with longer named enums.
ASKER
Below is code that should hopefully explain a bit better my need for this type of structure.
MaitreMind, I agree with keeping things simple. However, your approach does not suit my particular needs. These "enum"s will eventually contain more information and functionality than just a simple word conversion. Also xersoft is right in that the description may be long and I wouldn't want the enum to be that lengthy.
xersoft, I've modified your code a bit to something that seems to work. I would appreciate any comments on this approach. I did this to hopefully simplify things a bit more for myself. What is the benifit of using the Description attribute over an array of strings as I have below? I also am still deciding between a structure and class approach. Any thoughts on the matter?
Another thing is that when I assign a value to my variable below. Is there a way to get the Intellisense tooltip to automatically give me a list of possible values so that I don't have to do "Gender."? For example, when you use a boolean "True" and "False" automatically show up.
Dim x as Gender
x = Gender.NotSpecified
Public Structure Gender
#Region "Variables"
Private mvalue As Integer
Private Shared mNotSpecified As Gender = New Gender(0)
Private Shared mMale As Gender = New Gender(1)
Private Shared mFemale As Gender = New Gender(2)
'Contains descriptive text describing each each value
Private Shared aDescription() As String = New String() {"Gender has not been specified.", "Gender is male.", "Gender is female."}
'Contains value of object in format used for in third party device function.
Private Shared aDeviceValue() As String = New String() {"NONE", "MALE", "FEMALE"}
#End Region
#Region "Public Property Values"
Public Shared ReadOnly Property NotSpecified() As Gender
Get
Return mNotSpecified
End Get
End Property
Public Shared ReadOnly Property Male() As Gender
Get
Return mMale
End Get
End Property
Public Shared ReadOnly Property Female() As Gender
Get
Return mFemale
End Get
End Property
#End Region
#Region "Conversion Functions"
'Converts "enum" value to a english descriptive text
Private Function EnumToDescription(ByVal Value As Integer) As String
If Value >= LBound(aDescription) And Value <= UBound(aDescription) Then
Return aDescription(Value)
Else
Return String.Empty
End If
End Function
'Converts "enum" value to value used for third party function
Private Function EnumToDevice(ByVal Value As Integer) As String
If Value >= LBound(aDeviceValue) And Value <= UBound(aDeviceValue) Then
Return aDeviceValue(Value)
Else
Return String.Empty
End If
End Function
'Converts value from third party function to "enum" value
Private Shared Function DeviceToEnum(ByVal TranslatedValue As String) As Gender
For i As Integer = LBound(aDeviceValue) To UBound(aDeviceValue)
If aDeviceValue(i) = TranslatedValue Then
Return New Gender(i)
End If
Next
'could not find a description matching in this enum type
Return mNotSpecified
End Function
#End Region
#Region "Public Functions"
'Constuctor
Private Sub New(ByVal Value As Integer)
Me.mvalue = Value
End Sub
'Outputs to value used in third party plugin
Public Function ToDeviceValue() As String
Return Me.EnumToDevice(mvalue)
End Function
'Outputs a description of the value
Public Overrides Function ToString() As String
Return Me.EnumToDescription(mvalu e)
End Function
'Parse input from third party plugin to convert to "enum" value
Public Shared Function Parse(ByVal TranslatedValue As String) As Gender
Return DeviceToEnum(TranslatedVal ue)
End Function
Public Shared Operator =(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue = g2.mvalue Then Return True Else Return False
End Operator
Public Shared Operator <>(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue <> g2.mvalue Then Return True Else Return False
End Operator
#End Region
End Structure
MaitreMind, I agree with keeping things simple. However, your approach does not suit my particular needs. These "enum"s will eventually contain more information and functionality than just a simple word conversion. Also xersoft is right in that the description may be long and I wouldn't want the enum to be that lengthy.
xersoft, I've modified your code a bit to something that seems to work. I would appreciate any comments on this approach. I did this to hopefully simplify things a bit more for myself. What is the benifit of using the Description attribute over an array of strings as I have below? I also am still deciding between a structure and class approach. Any thoughts on the matter?
Another thing is that when I assign a value to my variable below. Is there a way to get the Intellisense tooltip to automatically give me a list of possible values so that I don't have to do "Gender."? For example, when you use a boolean "True" and "False" automatically show up.
Dim x as Gender
x = Gender.NotSpecified
Public Structure Gender
#Region "Variables"
Private mvalue As Integer
Private Shared mNotSpecified As Gender = New Gender(0)
Private Shared mMale As Gender = New Gender(1)
Private Shared mFemale As Gender = New Gender(2)
'Contains descriptive text describing each each value
Private Shared aDescription() As String = New String() {"Gender has not been specified.", "Gender is male.", "Gender is female."}
'Contains value of object in format used for in third party device function.
Private Shared aDeviceValue() As String = New String() {"NONE", "MALE", "FEMALE"}
#End Region
#Region "Public Property Values"
Public Shared ReadOnly Property NotSpecified() As Gender
Get
Return mNotSpecified
End Get
End Property
Public Shared ReadOnly Property Male() As Gender
Get
Return mMale
End Get
End Property
Public Shared ReadOnly Property Female() As Gender
Get
Return mFemale
End Get
End Property
#End Region
#Region "Conversion Functions"
'Converts "enum" value to a english descriptive text
Private Function EnumToDescription(ByVal Value As Integer) As String
If Value >= LBound(aDescription) And Value <= UBound(aDescription) Then
Return aDescription(Value)
Else
Return String.Empty
End If
End Function
'Converts "enum" value to value used for third party function
Private Function EnumToDevice(ByVal Value As Integer) As String
If Value >= LBound(aDeviceValue) And Value <= UBound(aDeviceValue) Then
Return aDeviceValue(Value)
Else
Return String.Empty
End If
End Function
'Converts value from third party function to "enum" value
Private Shared Function DeviceToEnum(ByVal TranslatedValue As String) As Gender
For i As Integer = LBound(aDeviceValue) To UBound(aDeviceValue)
If aDeviceValue(i) = TranslatedValue Then
Return New Gender(i)
End If
Next
'could not find a description matching in this enum type
Return mNotSpecified
End Function
#End Region
#Region "Public Functions"
'Constuctor
Private Sub New(ByVal Value As Integer)
Me.mvalue = Value
End Sub
'Outputs to value used in third party plugin
Public Function ToDeviceValue() As String
Return Me.EnumToDevice(mvalue)
End Function
'Outputs a description of the value
Public Overrides Function ToString() As String
Return Me.EnumToDescription(mvalu
End Function
'Parse input from third party plugin to convert to "enum" value
Public Shared Function Parse(ByVal TranslatedValue As String) As Gender
Return DeviceToEnum(TranslatedVal
End Function
Public Shared Operator =(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue = g2.mvalue Then Return True Else Return False
End Operator
Public Shared Operator <>(ByVal g1 As Gender, ByVal g2 As Gender) As Boolean
If g1.mvalue <> g2.mvalue Then Return True Else Return False
End Operator
#End Region
End Structure
What is the benifit of using the Description attribute over an array of strings as I have below?
-One benefit using the array over the attribute is that it’s probably faster. Reflection operations are slow. However one benefit of using the attribute description over the array is that the description is very closely coupled with the thing it is describing. I think either approach will work; I’d go with the attribute personally.
I also am still deciding between a structure and class approach. Any thoughts on the matter?
-I’d use a structure because you don’t have to use the new keyword to make a new instance of the object before you can use it example:
Dim x as Gender
Msgbox x.tostring
If you run those two lines in order the outcome will be different if Gender is a class. If Gender is a class the code will crash and say null reference exception. If you use a structure the same code will still work. With careful coding either a class or structure will work. I’d go with a structure personally.
Another thing is that when I assign a value to my variable below. Is there a way to get the Intellisense tooltip to automatically give me a list of possible values so that I don't have to do "Gender."? For example, when you use a boolean "True" and "False" automatically show up.
This one I have no idea about, short of using MaitreMind’s idea, which may or may not suit your needs for this project.
-One benefit using the array over the attribute is that it’s probably faster. Reflection operations are slow. However one benefit of using the attribute description over the array is that the description is very closely coupled with the thing it is describing. I think either approach will work; I’d go with the attribute personally.
I also am still deciding between a structure and class approach. Any thoughts on the matter?
-I’d use a structure because you don’t have to use the new keyword to make a new instance of the object before you can use it example:
Dim x as Gender
Msgbox x.tostring
If you run those two lines in order the outcome will be different if Gender is a class. If Gender is a class the code will crash and say null reference exception. If you use a structure the same code will still work. With careful coding either a class or structure will work. I’d go with a structure personally.
Another thing is that when I assign a value to my variable below. Is there a way to get the Intellisense tooltip to automatically give me a list of possible values so that I don't have to do "Gender."? For example, when you use a boolean "True" and "False" automatically show up.
This one I have no idea about, short of using MaitreMind’s idea, which may or may not suit your needs for this project.
Enums should not be long.
I use enums for loading fixed Dropdowns and the values are short.
What will you be doing with the class? Are you passing it around between tiers, keep in mind classes are reference types and structures are value types.
I create structures load them up and pass them between layers as MarshalByRefObjects so I get copies of the objects passes versus references to objects constantly marshalled.
If you put properties on the class for each Enum value you lose the purpose of the Enum with the Get and Set Properties exposed you get the enum choices. You also get the value by Intellisense, but if the enum text is too long it gets ridiculous.
MaitreMind
I use enums for loading fixed Dropdowns and the values are short.
What will you be doing with the class? Are you passing it around between tiers, keep in mind classes are reference types and structures are value types.
I create structures load them up and pass them between layers as MarshalByRefObjects so I get copies of the objects passes versus references to objects constantly marshalled.
If you put properties on the class for each Enum value you lose the purpose of the Enum with the Get and Set Properties exposed you get the enum choices. You also get the value by Intellisense, but if the enum text is too long it gets ridiculous.
MaitreMind
ASKER
Thanks to both of you for your help. I ended up splitting the points between the two of you for the following reasons.
I ended up going with using separate functions for parsing and converting the enum to a string and using a standard enum to pass around in my functions. I really wanted to keep things into a nice organized class, but unfortunately, after
Xersoft, you provided a solution that was close to what I orignally asked. It is extremely helpful but maybe too much.
MaitreMind, you fought hard and after that you've convinced me to keep things simple. Passing around this more object may be too much overhead.
Thanks to both of you.
I ended up going with using separate functions for parsing and converting the enum to a string and using a standard enum to pass around in my functions. I really wanted to keep things into a nice organized class, but unfortunately, after
Xersoft, you provided a solution that was close to what I orignally asked. It is extremely helpful but maybe too much.
MaitreMind, you fought hard and after that you've convinced me to keep things simple. Passing around this more object may be too much overhead.
Thanks to both of you.
Public Enum Gender
NotSpecified = 0
Male = 1
Female = 2
End Enum
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim g1, g2 As Gender
Dim sg1 As String
g1 = Gender.Male
sg1 = Type_ToString(g1)
g2 = DirectCast(Type_Parse(sg1,
End Sub
Public Function Type_ToString(ByVal myEnum As System.Enum) As String
'This method is not necessary since it is only a single line of code
Return [Enum].GetName(myEnum.GetT
End Function
Public Function Type_Parse(ByVal text As String, ByVal myEnum As System.Enum) As System.Enum
Dim val As System.Enum
For Each val In [Enum].GetValues(myEnum.Ge
If val.ToString.ToUpper = text.ToUpper Then
Return val
End If
Next
Return myEnum
End Function