有没有办法模仿类中共享方法的接口/契约以供泛型使用?

时间:2010-11-15 01:24:57

标签: vb.net

所以我实现了自己的Enum静态类形式,因此我可以将字符串与枚举值相关联。每个枚举类中的一个共享函数GetValue用于通过偏移量快速查找内部数组中的字符串值。虽然所有枚举类都实现了相同的功能,但它们的参数的数据类型不同,特定于每个类中的枚举。

所以我想要创建一个可以使用任何枚举的泛型类,将它作为泛型类型参数传递。但我无法找到一种方法来约束类型T,以便能够调用每个枚举的GetValue函数。这是一个接口派上用场的地方,但VB.NET禁止共享方法的接口。

我有一个我可以约束的基类,但是基类没有实现GetValue方法,我也无法定义它的通用版本,因为我需要依赖共享属性每个子类的顺序,以便GetValue做它的事情。

还有其他方法可以解决这个问题吗?

修改
这是枚举类的示例。父[{1}}并不特别,只托管常见的EBaseNameValue属性,以及两个共享运算符Type和{{1} }。想象一下,使用一些枚举类和泛型方法(或类),并需要通过泛型类型参数op_Equality访问op_Inequality成员。

GetValue

EDIT2: 以下是使用方法:

T

将打印Friend NotInheritable Class EExample Inherits EBase Private Sub New() End Sub Friend Shared Function GetValue(ByVal Name As String) As Enums Return Enums(Array.IndexOf(_Names, Name)) End Function 'Num of Enums defined. Friend Shared ReadOnly MaxEnums As Int32 = 5 'String literals. Private Shared ReadOnly _Names As String() = New String() _ {"one_adam", "two_boy", "three_charles", "four_david", "five_edward"} 'Enums. Friend Shared ReadOnly OneA As New Enums(_Names(0), 0) Friend Shared ReadOnly TwoB As New Enums(_Names(1), 1) Friend Shared ReadOnly ThreeC As New Enums(_Names(2), 2) Friend Shared ReadOnly FourD As New Enums(_Names(3), 3) Friend Shared ReadOnly FiveE As New Enums(_Names(4), 4) 'Enum Values Array. Friend Shared ReadOnly Values As Enums() = New Enums() _ {OneA, TwoB, ThreeC, FourD, FiveE} Friend NotInheritable Class Enums Inherits EBase Private Sub New() End Sub Friend Sub New(ByVal Name As String, ByVal Value As Int32) MyBase.Name = Name MyBase.Value = Value MyBase.Type = GetType(Enums) End Sub End Class End Class

2 个答案:

答案 0 :(得分:1)

这是一个解决方案:

Friend NotInheritable Class EExample
    Inherits EBase

    Protected Sub New()
    End Sub

    Protected Overrides Function BuildValues() As EBase.Enums()
        Return New Enums() _
        { _
            Build(Of EExample)("one_adam", 0), _
            Build(Of EExample)("two_boy", 1), _
            Build(Of EExample)("three_charles", 2), _
            Build(Of EExample)("four_david", 3), _
            Build(Of EExample)("five_edward", 4) _
        }
    End Function

    Private Shared _instance As EExample = New EExample()

    Friend Shared ReadOnly OneA As Enums = _instance.Values(0)
    Friend Shared ReadOnly TwoB As Enums = _instance.Values(1)
    Friend Shared ReadOnly ThreeC As Enums = _instance.Values(2)
    Friend Shared ReadOnly FourD As Enums = _instance.Values(3)
    Friend Shared ReadOnly FiveE As Enums = _instance.Values(4)

End Class

EBase然后看起来像这样:

Public MustInherit Class EBase

    Protected MustOverride Function BuildValues() As Enums()

    Private _values As EBase.Enums()

    Friend ReadOnly Property Values() As EBase.Enums()
        Get
            If _values Is Nothing Then
                _values = Me.BuildValues()
            End If
            Return _values
        End Get
    End Property

    Friend ReadOnly MaxAlterEnums As Int32 = Me.Values.Length

    Friend Function GetValue(ByVal Name As String) As Enums
        Return Me.Values.Where(Function(n) n.Name = Name).FirstOrDefault()
    End Function

    Friend Shared Function Build(Of T As EBase)(ByVal name As String, ByVal value As Int32) As Enums
        Return New Enums(name, value, GetType(T))
    End Function

    Public Class Enums
        Public Sub New(ByVal name As String, ByVal value As Int32, ByVal type As Type)
            Me.Name = name
            Me.Value = value
            Me.Type = type
        End Sub
        Private _name As String
        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(ByVal Value As String)
                _name = Value
            End Set
        End Property
        Private _value As Integer
        Public Property Value() As Integer
            Get
                Return _value
            End Get
            Set(ByVal Value As Integer)
                _value = Value
            End Set
        End Property
        Private _type As Type
        Public Property Type() As Type
            Get
                Return _type
            End Get
            Set(ByVal Value As Type)
                _type = Value
            End Set
        End Property
    End Class

End Class

现在您的示例代码与以前完全一样:

    Dim Foo As EExample.Enums
    Foo = EExample.TwoB
    Debug.Print(Foo.Name)

您正在处理代码实现的普通实例。唯一的Shared值是五个Enums和一个私有_instance变量。

您现在可以限制EBase

这对你有用吗?


Kumba指出我没有在GetValue类上公开EExample函数。

只需将其添加到EExample

即可
    Friend Shared Function GetValue(ByVal Name As String) As Enums
        Return _instance.GetValue(Name)
    End Function

答案 1 :(得分:0)

哇,这听起来确实很快就会变得越来越快。你确定你需要这一切吗?

通过创建一个类,在同一个文件中包含枚举(或者甚至嵌套在同一个命名空间中,如果您愿意),然后使用.ToFriendlyName(),将字符串与枚举值相关联不是更容易吗?提取字符串的方法(即,如果它是为人类设计的),如果你需要另一种方法,你可以创建一个具有字符串参数的类的构造函数,并存储相关的枚举。

您真的需要所有数组,继承和.GetValue重载吗?也许我是误会,但从你最初的描述来看,这听起来似乎解决方案可能会被过度设计。

您能否提供更多细节,特别是关于您从哪开始的“枚举静态类”?你试图解决的根本问题是什么?