在VB.NET中实现“可选委托”的最佳方法是什么?

时间:2013-01-25 16:32:30

标签: .net vb.net

我来自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中实现了委托模式惯用语吗?)

2 个答案:

答案 0 :(得分:4)

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

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...")

答案 1 :(得分:2)

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

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&#39; point是最好的(谁应该把它作为一个答案,所以你可以接受它!):创建一个NullLogger对象并使用它。然后抽象&#34;我不想记录&#34;隐藏在呼叫者之外。