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 FunctionEnd ClassPublic 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 FunctionEnd ClassTesting 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 SubEnd ModuleCan you spot anything wrong or missing or a possible improvement?
Implementing a StringEnum
design patterns;vb.net;template;enum