2012-02-17 2 views
1

Existe-t-il un moyen de n'utiliser que des méthodes de classe de base uniquement?Base-Class seulement Méthodes?

Je contourne l'utilisation d'un module, mais cela sépare la fonctionnalité qui ne sera utilisée que par la classe de base.

je pense était sur la ligne de ce qui suit

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 

Alors maintenant, quand

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

mais

Dim d1 = Digit. 

ne serait pas montrer la méthode Parse.

Alors, comment cela peut-il être fait? (Si possible)

EDIT

Implémentations actuelles Cela devrait vraiment une classe de base seulement méthode dans la classe Token

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 

Token (Base) Classe

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 

Chiffre Classe

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

Et à quoi cela servirait-il? –

+0

Qu'est-ce que 'CharReader'? J'aurais besoin de savoir cela pour vous aider avec le problème 'Parse'. –

+0

Peu importe le type de CharReader. –

Répondre

2

Ce type de relation brise vraiment les concepts OO. Si un type parent fournit une fonctionnalité publique, alors l'enfant devrait aussi (pensez que l'enfant est un parent).

Le type de fonctionnalité que vous souhaitez peut facilement être obtenu via la composition (les chiffres contiendraient une instance de Token et de proxy quels que soient les appels nécessaires à cette instance) plutôt que l'héritage.

+0

J'ai besoin que Digit soit un sous-type de Token, car ils peuvent être placés dans un conteneur de type safe plutôt que d'utiliser un objet. –

+0

@AdamSpeight - Créez ensuite une interface que vous pouvez appliquer à la fois au jeton et au chiffre qui n'expose que les fonctionnalités dont vous avez besoin. –

+0

L'analyse doit être statique/partagée. Puisque le code qui sera contenu dans la méthode Parse est commun à ** tous ** instanciés de la classe, il devrait vraiment être partagé. Donc, cette exigence l'exclut. Elle exclut également les interfaces. Ce dont j'ai besoin, c'est un ** objet de classe ** lui-même pas une instance de cette classe. –

0

Si CharReader implémente IConvertible, vous pouvez le convertir en autres types avec System.Convert. Les types standard comme Boolean, String, Char, Int32, Double, etc. mettent en œuvre 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 peut être caché en observant avec une méthode non publique

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

Notez que cela ne fonctionne que pour les méthodes partagées, puisque vous les accès par le nom du type et pas à travers une instance.

+0

Mais je veux .Parse ne soit accessible que sur la classe Token. Token.Parse (Of Digit) pas Digit.Parse() ou toute autre sous-classe dérivée de Token. –

+0

Si vous déclarez 'Parse' avec le mot clé 'Shadows' et que vous êtes protégé et que vous tapez' Digit.', intellisense n'affiche aucune méthode' Parse'! –

1

n'afficherait pas la méthode Parse.

Je ne suis pas sûr que je suis, mais vous semblez seulement préoccupé par IntelliSense montrant la méthode.C'est facile à résoudre avec 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

L'analyse doit être statique/partagée. Puisque le code qui sera contenu dans la méthode Parse est commun à ** tous ** instanciés de la classe, il devrait vraiment être partagé. Donc, cette exigence l'exclut. Elle exclut également les interfaces. Ce dont j'ai besoin, c'est un ** objet de classe ** lui-même pas une instance de cette classe. –

+0

Donc, juste les faire partager ensuite. Post mis à jour, fonctionne toujours. C'est aussi loin que vous pouvez le pousser sans redéfinir les principes de POO. –

+0

Mais vous pouvez toujours écrire Digit.Parse(). Le PARSE ne devrait exister que sur l'objet ** Token **, aucun de ses objets descendants n'étant invisible de l'intellisense. –

Questions connexes