0

我有一个基类Base和派生自它Sorter的类。与派生和Parser相同的事情。 有一个类型的字段,有一个字段。我之所以使用一个类,是因为两者都必须写一个日志。这是我的代码:BaseResultSorterResultParserResultBaseResultBaseResultBaseResultLogBaseParserSorter

Public MustInherit Class Base
    Public Result As BaseResult
    Event LogChanged()
    Protected Sub AddLogLine(ByVal _logString As String)
        If Not String.IsNullOrWhiteSpace(_logString) Then Result.Log.Add(_logString)
        RaiseEvent LogChanged()
    End Sub
End Class

Public Class Sorter
    Inherits Base
    Public Shadows Result As SorterResult
    Sub New()
        Result = New SorterResult With {.Log = New List(Of String)}
    End Sub
    Sub Go()
        AddLogLine("Sorter started")
    End Sub
End Class

Public Class Parser
    Inherits Base
    Public Shadows Result As ParserResult

    Sub New()
        Result = New ParserResult With {.Log = New List(Of String)}
    End Sub
    Sub Go()
        AddLogLine("Sorter started")
    End Sub
End Class

Public MustInherit Class BaseResult
    Public Log As List(Of String)
End Class

Public Class SorterResult
    Inherits BaseResult
    '//SorterResult fields
End Class

Public Class ParserResult
    Inherits BaseResult
    '//ParsedResult fields
End Class

这里的问题是编译器sais(在下图中):在此处输入图像描述

“变量‘Result’与基类‘Base’中的变量‘Result’冲突,应声明为‘Shadows’。” 当我使用 Shadows 关键字时,警告消失了,但我在这一行得到一个空引用异常,因为Result字段是Nothing

If Not String.IsNullOrWhiteSpace(_logString) Then Result.Log.Add(_logString)

我无法Result在类构造函数中为变量赋值Base,因为它必须是SorterResultinSorterParserResultin类型Parser。这里的常规模式是什么?对不起我的英语不好。

在此处输入图像描述

4

1 回答 1

2

使用泛型

Public MustInherit Class Base(Of TResult As BaseResult)
    Public Result As TResult

    Event LogChanged()

    Protected Sub AddLogLine(ByVal _logString As String)
        If Not String.IsNullOrEmpty(_logString) Then Result.Log.Add(_logString)
        RaiseEvent LogChanged()
    End Sub

    Public MustOverride Sub Go()
End Class

Public Class Sorter
    Inherits Base(Of SorterResult)

    Sub New()
        Result = New SorterResult With {.Log = New List(Of String)}
    End Sub

    Public Overrides Sub Go()
        AddLogLine("Sorter started")
    End Sub
End Class

Public Class Parser
    Inherits Base(Of ParserResult)

    Sub New()
        Result = New ParserResult With {.Log = New List(Of String)}
    End Sub

    Public Overrides Sub Go()
        AddLogLine("Sorter started")
    End Sub
End Class

然而,这并不是一个“漂亮”的继承层次结构。继承应该形成像“学生就是人”这样的关系,其中student派生自person。分类器和解析器有什么共同点?他们是一个Base?他们是伐木工吗?他们是命令(如建议的Go方法)?这里需要继承吗?使用聚合不是更合适吗?我会声明一个完全独立的记录器类并将其注入到类中。这使您更加灵活,因为它使您能够注入不同类型的记录器。

Public MustInherit Class Logger
    Public Event LogChanged()

    Public MustOverride Sub AddLogLine(ByVal message As String)

    Protected Sub OnLogChanged()
        RaiseEvent LogChanged()
    End Sub
End Class

Public Class TextFileLogger
    Inherits Logger

    Public Overrides Sub AddLogLine(ByVal message As String)
        If Not String.IsNullOrEmpty(message) Then
            'TODO: Write message to log file
            OnLogChanged()
        End If
    End Sub
End Class

你可以像这样注入它:

Public Class SomeConsumerClass
    Private _logger As Logger

    Sub New(ByVal logger As Logger)
        _logger = logger
    End Sub

    Public Sub DoSomething()
        _logger.AddLogLine("Did something!")
    End Sub
End Class

像这样使用:

Dim obj As New SomeConsumerClass(New TextFileLogger())
obj.DoSomething()

如果您有另一种记录器(XmlFileLogger、StringListLogger、DatabaseLogger...),现在可以轻松使用它,而无需更改所有使用它的类。

也许您甚至应该只有一个全局记录器:

Dim globalLogger As New TextFileLogger()
Dim sorter As New Sorter(globalLogger)
Dim parser As New Parser(globalLogger)
于 2014-11-09T18:20:14.503 回答