Методы только базового класса? - PullRequest
1 голос
/ 18 февраля 2012

Есть ли способ только для базовых классов?

У меня есть обходной путь использования модуля, но это разделяет функциональность, которая будет использоваться только базовым классом.

Я думал о следующей

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.

не показывает метод анализа.

Так как это можно сделать? (Если возможно вообще)

EDIT

Текущие реализации Это должен быть метод только базового класса в классе токенов

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

Класс цифр

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

Ответы [ 3 ]

2 голосов
/ 18 февраля 2012

Такие отношения действительно нарушают концепции ОО. Если родительский тип предоставляет общедоступную функциональность, то и ребенок должен (подумайте, что Child - это Parent).

Тип требуемой функциональности может быть легко достигнут с помощью композиции (Digit будет содержать экземпляр токена и прокси-сервера, какие бы вызовы ни были необходимы для этого экземпляра), а не наследование.

1 голос
/ 18 февраля 2012

не показывает метод анализа.

Не уверен, что я следую, но вы, кажется, обеспокоены только тем, что IntelliSense показывает метод. Это легко решить с помощью 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 голосов
/ 18 февраля 2012

Если CharReader реализует IConvertible, вы можете преобразовать его в другие типы с помощью System.Convert. Стандартные типы, такие как Boolean, String, 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)

Обратите внимание, что это работает только для общих методов, поскольку вы получаете к ним доступ через имя типа, а не через экземпляр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...