2012-02-17 51 views
1

有没有一种只有基类的方法?只有基础类方法?

我有一个使用模块的工作,但这分开了只能由基类使用的功能。

我认为在以下

Public MustInherit Class Token 
    ' Token stuff 
    NotInheritable Shared Function Parse(Of T As Token)(CR As CharReader) As T 
    ' Would also be good to be able to do the following without resorting 
    ' to the reflection based bodgery. 
    Return T.Parser(CR) 
    End Function 
End Class 

Public Class Digit 
    Inherit Token 
    ' Digit Stuff 
    Protected Shared Function Parser(CR As CharReader) As Digit 
    If CR.Current.HasValue = False Then Return Nothing 
     Case Select CR.Value 
     Case "0"c To "9"c 
      Return New Digit(CR.Index,0) 
     Case Else 
     Return False 
     End Select 
    End Function 

行所以现在当

Dim d0 = Token.Parse(Of Digit)(cr) 

Dim d1 = Digit. 

不会显示Parse方法。

那么这怎么做呢? (如果可能的话)

编辑

当前实现 这应该真的是一个基类只能在令牌类

Public Module TokenModule 
    Public Function Parse(Of T As Token)(cr As CharReader) As T 
    ' 
    ' Here Be Nasty Reflection Based Bodge Job 
    ' 
    ' Why? What I want to write. (Call a static method on the generic (constrianed) type  specifier.) 
    ' 
    ' Return T.Parser(cr) 
    ' 
    ' Start Bodgery { 
    Dim tt As T 
    tt = GetType(T).InvokeMember("Parser", 
           Reflection.BindingFlags.InvokeMethod + 
           Reflection.BindingFlags.NonPublic + 
           Reflection.BindingFlags.Static, Nothing, tt, {cr}) 
    Return tt 
    ' } End Bodgery 
End Function 
End Module 

令牌(基地)类

Public MustInherit Class Token 
    Private _Index As Integer 
    Private _Count As Integer 
    Protected Friend Sub New(ByVal Index As Integer, Count As Integer) 
    _Index = Index : _Count = Count 
    End Sub 
    Public ReadOnly Property Index As Integer 
    Get 
     Return _Index 
    End Get 
    End Property 
    Public ReadOnly Property Count As Integer 
    Get 
     Return _Count 
    End Get 
    End Property 
    Protected Shared Function Parser(cr As CharReader) As Token 
    Return Nothing 
    End Function 
End Class 
方法

Digit Class

Public Class Digit 
    Inherits Token.Token 
    Private Sub New(ByVal Index As Integer, Count As Integer) 
    MyBase.New(Index, Count) 
    End Sub 
    Protected Overloads Shared Function Parser(cr As CharReader) As Digit 
    Dim crc = cr.Current 
    If crc.HasValue = False Then Return Nothing 
     Select Case crc.Value 
     Case "0"c To "9"c 
      Return New Digit(cr.Index, 1) 
     Case Else 
      Return Nothing 
     End Select 
    End Function 
End Class 
+0

这将是什么使用? – 2012-02-17 22:32:58

+0

什么是'CharReader'?我需要知道,以帮助你解决'Parse'问题。 – 2012-02-17 22:46:00

+0

什么CharReader它可以是任何类型并不重要。 – 2012-02-17 23:13:22

回答

2

这种关系真的打破了面向对象的概念。如果父类型提供公共功能,那么孩子也应该(认为孩子是父母)。

您希望的功能类型可以通过组合(数字将包含令牌和代理的实例,无论对该实例调用什么)而非继承来轻松实现。

+0

我需要Digit为Token的子类型,因为它们可以放入类型安全的容器而不是使用对象。 – 2012-02-17 23:16:58

+0

@AdamSpeight - 然后创建一个接口,您可以将它应用于仅显示您需要的功能的令牌和数字。 – 2012-02-18 04:51:52

+0

解析应该是静态/共享的。由于Parse方法中包含的代码对于该类的所有实例都是通用的,因此它应该真正共享。所以这个要求规定了这一点,它也排除了接口。我需要的是一个**类对象**本身不是该类的一个实例。 – 2012-02-19 11:07:49

0

如果CharReader implements IConvertible,您可以将它转换为System.Convert的其他类型。标准类型如BooleanString,Char,Int32,Double等实施IConvertible

Shared Function Parse(Of T As Token)(ByVal CR As CharReader) As T 
    Return DirectCast(Convert.ChangeType(CR, GetType(T)), T) 
End Function 

-

Parse可以通过非公开方式遮蔽它

Protected Shared Shadows Function Parse(ByVal CR As CharReader) As Digit 
        ^
        | 
      (note the Shadows keyword) 

请注意,这仅适用于共享的方法,因为你通过类型名称访问这些被隐藏,不是通过一个实例。

+0

但是我希望.Parse只能在Token类中访问。 Token.Parse(Of Digit)不是Digit.Parse()或Token的任何其他派生子类。 – 2012-02-17 23:45:15

+0

如果你用'Shadows'关键字声明'Parse'并且被保护并且输入'Digit.',intellisense将不会显示任何'Parse'方法! – 2012-02-17 23:50:35

1

不会显示分析方法。

不确定我关注,但您只关注显示该方法的智能感知。这很容易解决与EditorBrowsableAttribute:

Imports System.ComponentModel 
... 
Class Token 
    Public Shared Sub Parse() 
     '' etc 
    End Sub 
End Class 

Class Digit 
    Inherits Token 

    <EditorBrowsable(EditorBrowsableState.Never)> _ 
    Public Shared Shadows Sub Parse() 
     Token.Parse() 
    End Sub 
End Class 
+0

解析应该是静态/共享的。由于Parse方法中包含的代码对于该类的所有实例都是通用的,因此它应该真正共享。所以这个要求规定了这一点,它也排除了接口。我需要的是一个**类对象**本身不是该类的一个实例。 – 2012-02-19 11:05:06

+0

所以,只要让他们分享然后。发布更新,仍然有效。无需重新设计面向对象的原则,就可以推动它。 – 2012-02-19 11:26:25

+0

但是你仍然可以写Digit.Parse()。 PARSE应该只存在于** Token **对象中,而不是它的任何后代对象,而不是从intellisense中不可见。 – 2012-02-19 15:35:50