This is to be used like an Enum (as parameter mostly), but for string
(Using .NET 3.5)
Actual implementation:
Public MustInherit Class StringEnum(Of T As {New, StringEnum(Of T)})
Private Shared ReadOnly _lock As New Object
Private Shared ReadOnly _cache As New Dictionary(Of String, T)
Private _value As String
Public ReadOnly Property Value() As String
Get
Return _value
End Get
End Property
Friend Sub New()
End Sub
Public Shared Function GetEnum(value As String) As T
Dim se As T = Nothing
If Not _cache.TryGetValue(value, se) Then
Return Nothing
End If
Return se
End Function
Public Overrides Function Equals(obj As Object) As Boolean
Return obj IsNot Nothing AndAlso String.Equals(_value, DirectCast(obj, T)._value, StringComparison.Ordinal)
End Function
Public Overrides Function GetHashCode() As Integer
Return _value.GetHashCode
End Function
Public Overrides Function ToString() As String
Return _value
End Function
Public Shared Widening Operator CType(ByVal se As StringEnum(Of T)) As String
Return se.Value
End Operator
Public Shared Operator =(se1 As StringEnum(Of T), se2 As StringEnum(Of T)) As Boolean
Return Object.Equals(se1, se2)
End Operator
Public Shared Operator <>(se1 As StringEnum(Of T), se2 As StringEnum(Of T)) As Boolean
Return Not (se1 = se2)
End Operator
Friend Shared Function CacheHelper(value As String) As T
Dim se As T = Nothing
SyncLock _lock
If Not _cache.TryGetValue(value, se) Then
se = New T()
se._value = value
_cache.Add(se.Value, se)
End If
End SyncLock
Return se
End Function
End Class
Public Class ValueStringEnum
Inherits StringEnum(Of valueStringEnum)
Public Shared ReadOnly Property Value1() As valueStringEnum
Get
Return CacheHelper("Value 1")
End Get
End Property
Public Shared ReadOnly Property Value2() As valueStringEnum
Get
Return CacheHelper("Value 2")
End Get
End Property
Public Shared ReadOnly Property Value3() As valueStringEnum
Get
Return CacheHelper("Value 3")
End Get
End Property
Public Shared ReadOnly Property Value4() As valueStringEnum
Get
Return CacheHelper("Value 4")
End Get
End Property
'these 3 below are annoying but can't easily reuse the one in base class
Public Overrides Function Equals(obj As Object) As Boolean
Return MyBase.Equals(obj)
End Function
Public Overrides Function GetHashCode() As Integer
Return MyBase.GetHashCode
End Function
Public Overrides Function ToString() As String
Return MyBase.ToString
End Function
End Class
Testing the implementation:
Module Module1
Sub Main()
Dim v1 As ValueStringEnum = ValueStringEnum.Value1
Dim v2 As ValueStringEnum = ValueStringEnum.Value2
Dim v3 As ValueStringEnum = ValueStringEnum.Value3
Dim v4 As ValueStringEnum = ValueStringEnum.Value4
Dim vS1 As String = v1
Dim vS2 As String = v2
Dim vS3 As String = v3
Dim vS4 As String = v4
Dim vc1 As ValueStringEnum = ValueStringEnum.GetEnum(vS1)
Dim vc2 As ValueStringEnum = ValueStringEnum.GetEnum(vS2)
Dim vc3 As ValueStringEnum = ValueStringEnum.GetEnum(vS3)
Dim vc4 As ValueStringEnum = ValueStringEnum.GetEnum(vS4)
test(v4) 'print Value 4
test(ValueStringEnum.Value2) 'print Value 2
Console.WriteLine("vc4.equals(v4) " & vc4.Equals(v4)) 'true
Console.WriteLine("vc4.equals(v2) " & vc4.Equals(v2)) 'false
Console.WriteLine("vc4 = v4 " & (vc4 = v4)) 'true
Console.WriteLine("vc4 = v2 " & (vc4 = v2)) 'false
Console.WriteLine("vc4 <> v4" & (vc4 <> v4)) 'false
Console.WriteLine("vc4 <> v2 " & (vc4 <> v2)) 'true
Console.WriteLine("vc4 = Value 4 " & (vc4 = "Value 4")) 'true
Console.WriteLine("vc4 = Value 2 " & (vc4 = "Value 2")) 'false
Console.WriteLine("vc4 <> Value 4 " & (vc4 <> "Value 4")) 'false
Console.WriteLine("vc4 <> Value 2" & (vc4 <> "Value 2")) 'true
End Sub
Sub test(value As ValueStringEnum)
Console.WriteLine(value)
End Sub
End Module
Can you spot anything wrong or missing or a possible improvement?