2

我来自 Objective-C 背景,我正在编写一些包含委托的 VB.NET。我有一个Worker执行某些任务的类。此类的属性之一是一个ILogger对象,它具有附加到某个日志文件的方法。(我希望我的Worker对象与日志记录分离,这将由我的 GUI 处理。)在 Objective-C 中,我可以声明

@property (nonatomic, strong) id<LoggingDelegate> logger;

然后在我的代码上撒上类似的行

[logger appendToLog:@"Beginning polarity reversal..."];

在 Objective-C 中,logger实际上不需要将其设置为对象即可。如果它是一个空引用(Objective-C 中的“nil”),appendToLog:则运行时会默默地忽略该消息。

在 VB.NET 中,我可以做类似的事情:

Public Property logger As ILogger

logger.AppendText("Beginning polarity reversal...")

但当然,logger实际上需要设置为一个对象才能使其工作。处理我的工作人员没有附加记录器对象的情况的惯用方法是什么?(更一般地说,我在 VB.NET 中实现的委托模式是惯用的吗?)

4

2 回答 2

4

每次使用可选对象时,都可以先检查它是否为空,例如:

If logger IsNot Nothing Then
    logger.AppendText("Beginning polarity reversal...")
End If

或者,您可以创建一个为您执行额外检查的私有方法:

Private Sub AppendTextToLog(text As String)
    If logger IsNot Nothing Then
        logger.AppendText("Beginning polarity reversal...")
    End If
End Sub

或者,正如 vcsjones 建议的那样,您可以将该属性默认为一个虚拟对象:

Public Class MyClass
    Private Class DummyLogger
        Implements ILogger

        Public Sub AppendText(text As String) Implements ILogger.AppendText
            ' Do nothing
        End Sub
    End Class

    Public Property Logger As ILogger
        Get
            Return _logger
        End Get
        Set(ByVal value As ILogger)
            _logger = value
        End Set
    End Property
    Private _logger As ILogger = New DummyLogger()

    Public Sub DoWork()
        _logger.AppendText("Beginning polarity reversal...")
    End Sub
End Class

或者,最接近 VB.NET 中“可选委托”的东西实际上是Event

Public Class MyClass
    Public Event AppendText(text As String)

    Public Sub DoWork()
        RaiseEvent AppendText("Beginning polarity reversal...")
    End Sub
End Class

更新

从 VB 14.0 (Visual Studio 2015) 开始,您现在可以使用?.运算符(称为“空条件”运算符):

logger?.AppendText("Beginning polarity reversal...")

或者,如果您想使用实际的委托,您也可以使用与委托相同的运算符。因此,如果您有一个名为 的委托变量appendToLog,您可以调用:

appendToLog?.Invoke("Beginning polarity reversal...")
于 2013-01-25T17:32:35.977 回答
2

我暂时搁置我的道德信念,指出可以在空对象上调用扩展方法。所以如果你写:

Module M
    <Extension>
    Public Sub LogIfNotNull(logger As ILogger, message As String)
        If logger IsNot Nothing Then
            logger.AppendText(message)
        End If
   End Sub
End Module

您可以使用此扩展方法写入您的 ILogger,它会做您想做的事。现在,我不建议将您的地址放在这段代码附近,因为下一个找到它的开发人员可能会想知道您住在哪里。说够了。

vcsjones 的观点是最好的(谁真的应该把它写成答案,这样你才能接受它!):制作一个 NullLogger 对象并使用它。然后对调用者隐藏“我不想记录”的抽象。

于 2013-01-25T17:39:17.000 回答